我是Python的runpy模块的维护者,也是当前导入系统的维护者之一。尽管我们的导入系统非常灵活,但我建议不要在不作任何调整的情况下批量采用它-由于出于向后兼容性的考虑,有些事情比原本需要的要尴尬得多。
用Python中的PEP 302伤害的一件事是,我们将核心导入系统转换为使用它需要花费多长时间。在过去十年的大部分时间里,任何使用导入挂钩完成任何复杂工作的人都被困在实现两个方面:一个处理符合PEP 302的加载程序(例如zip导入),第二个处理基于标准文件系统的导入机制。仅在即将发布的3.3版本中,处理PEP 302加载程序还将处理通过标准文件系统导入机制导入的模块。如果可以避免,请尽量不要重复该错误。
PEP 420(为Python 3.3实现)对协议做了一些补充,以允许导入者为名称空间包贡献部分。它还解决了Finder API定义中的命名问题(有效地用更准确的“ find_loader”替换了误命名的“ find_module”)。希望到3.3rc1在几周后发布时,所有这些都应该在语言规范中得到更清晰的记录。
另一个值得注意的问题是,PEP 302中专门记录的方法具有太多的过程全局状态。不要沿着这条路走-尝试将状态封装在一个更一致的对象模型中,这样选择性地导入其他模块会稍微容易一些(C扩展模块是使任何此类封装完全有效的祸根,但即使是某种程度的封装会有所帮助)。
PEP 406(http://www.python.org/dev/peps/pep-0406/)讨论了具有改进的状态封装的Python方法的可能向后兼容的发展。但是,如果从一开始就具有封装的状态模型,则可以相应地定义API,并避免让导入程序和加载程序完全访问全局状态(而是将引用传递给活动引擎)。
PEP 302中另一个缺少的部分是能够要求进口商对由该进口商提供的模块进行迭代的功能(这对于诸如冻结实用程序和提取文档字符串的自动文档实用程序之类的操作是必需的)。由于它非常有用,因此最好从一开始就对其进行标准化:http : //docs.python.org/dev/library/pkgutil#pkgutil.iter_modules(我们可能最终会将其提升为正式指定的格式Python 3.4中的API)
我的最后一句话是,您应该仔细研究导入系统和加载程序对象之间的责任划分。特别是,考虑将“ load_module” API分为单独的“ init_module”和“ exec_module”步骤。那应该允许您最小化加载程序需要与导入状态直接交互的程度。
PEP 302和importlib是建立更灵活的导入系统的一个很好的起点,但是绝对有我们应该避免的错误。