The History of Python

2009年4月30日星期四

模块动态载入机制

英文原文链接:http://python-history.blogspot.com/2009/03/dynamically-loaded-modules.html


原文作者:Guido van Rossum


Python的实现架构使得从一开始就容易使用C写扩展模块。然而最初动态连接技术相当不成熟以至于只能在构建时由Python解释器时静态链接扩展。因此C扩展模块需要附带shell脚本用以给Python和它的扩展模块生成Makefile文件。

虽然这个方法对小项目来说可以凑活,Python社区产生新扩展模块的速度之快出乎意料,这样可以单独编译和加载模块就成了迫切需求。很快,有人贡献了平台相关的动态链接API编程接口,允许import语句在磁盘上如同以前处理“.py”文件一样寻找共享库。CVS日志中最早提到动态加载是1992年1月的事情,支持主流操作系统要到1994年底才完成。


动态链接支持被证明是很有用的技术,可惜却带来了维护上的困扰。每个平台有各自独有的API,有的平台还有附加的限制。1995年1月,重构动态链接支持之后,所有相关代码集中在同一个源文件中。然而,这只是集合成一个到处都有条件编译指令(#ifdef)的大文件。1999年12月,在Greg Stein的帮助下,再次重构将每个平台相关的代码保存为专为该平台(或满足同样条件的一系列平台)的设定文件。


虽然Python支持动态加载模块,对许多用户来说,构建这些模块的过程仍然感觉神秘莫测。许多用户,而且数量还在增长开始构建模块--尤其是SWIG为代表的扩展构建工具出现之后。但是,当用户准备发布一个扩展模块时又要面对巨大障碍了,需要处理模块在各种平台、编译器、连接器的各种组合情况。以至于有时用户需要自己动手写Makefile文件和设置编译器连接器参数的配置脚本。还有一种选择就是用户也可以将自己的模块添加到Python的Makefile,然后设定合适选项后执行部分Python重构建。但是这需要用户手头上就有Python源代码。


最终,distuils这一Python扩展构建工具出现了,致力于统一解决模块构建和安装问题。必要的编译器和连接器参数写入一个Python makefile文件作为数据文件,在distutils构建扩展模块时会用到。主要由Greg Ward完成,distutils第一个版本单独发布以支持以前的Python版本。从Python1.6开始,Python把distutils当做标准库模块包含进来。


要提到的是distutils能做的远比从C源代码构建扩展模块要多。它也可以安装纯Python代码的模块和包,创建Windows可执行安装包,以及运行SWIG等第三方工具。哎,distutils由于复杂而被很多人诅咒,也没有得到应有的维护。结果,最近又有第三方替代方案(特别是ez_install,也就是“eggs”)开始流行,可悲的导致了开发社区的分裂,而且也由于同样难以使用在每当不灵的时候就被抱怨。看起来,这问题本质上就是一个难事吧。

没有评论: