使用Python的“ PEP-302新导入挂钩”的经验[关闭]


40

我是Ruby(CRuby)的开发人员之一。我们正在开发Ruby 2.0版本(计划于2012年2月发布)。

Python具有“ PEP302:新导入挂钩”(2003年):

该PEP建议添加一组新的导入挂钩,以更好地自定义Python导入机制。与当前的导入钩子相反,可以将一种新型的钩子注入到现有方案中,从而可以对如何找到模块以及如何加载模块进行更精细的控制。

我们正在考虑将类似于PEP302的功能引入Ruby 2.0(CRuby 2.0)。我想提出一个可以说服Matz的建议。当前,CRuby只能以标准方式从文件系统加载脚本。

如果您对PEP 302有任何经验或考虑,请分享。

例:

  1. 这是一个很棒的规格。无需更改。
  2. 差不多不错,但是有这个问题...
  3. 如果我可以回到2003年,那么我会将规范更改为...

6
哇,YARV家伙自己,您好,欢迎来到程序员!;)在Stack Exchange上,我们真的不喜欢开放式讨论,而是喜欢解决特定的问题(快速阅读我们的FAQ)-我想这是您的问题为什么在Stack Overflow上被关闭,并且已经有一个在这里结束投票。您应该尝试使其更加具体-您是否对引起这个问题的PEP 302感到特别关注?
扬尼斯,2012年

4
谢谢您的评论,Yannis。我想我想讨论“软件体系结构”。PEP302似乎是功能强大且通用的框架,可以在python解释器上扩展自己的加载器。但是,强大的功能存在诸如过度使用(生成魔术代码)之类的风险,从而妨碍了解释器的优化。因此,我想知道此扩展框架对python用户解释器开发人员而言是否合适。我相信研究历史将有助于我对Ruby 2.0做出好的规范。
ichi田耕一2012年

谢谢您修改我的问题。很抱歉,如果这个问题不是更可取的。
ichi田耕一2012年

这是一个很好的例子,说明一个表面上未能通过我们的“观点调查”测试的问题如何可以证明具有惊人的价值。
罗斯·帕特森

Answers:


47

我是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是建立更灵活的导入系统的一个很好的起点,但是绝对有我们应该避免的错误。


1
他们不是完呢,而且全面导入系统文件的初稿,可以发现docs.python.org/dev/reference/import
ncoghlan

1
python.org/dev/peps/pep-0451是Python 3.4的Python导入系统的更新,在这里解决了Brett和我的许多评论。
ncoghlan 2014年

28

在ncoghlan旁边,我是Python导入系统的另一个维护者,也是其当前实现的作者importlib(http://docs.python.org/dev/py3k/library/importlib.html)。尼克所说的一切我都同意,所以我只想补充一些信息。

首先,不要过分直接依赖PEP 302,而要看看importlib在抽象基类等方面提供了什么。为了向后兼容,事物必须与PEP 302兼容,但是我必须添加一些自己的API,以完善对真正灵活性的支持。

另一个重要的一点是,您为开发人员提供了两种灵活性。一种是能够将代码存储为单个文件(我称其为导入的存储后端),而不是直接将其存储在文件系统中,例如,这允许代码保存在zip文件,sqlite数据库等中。 。另一种支持是允许控件以某种方式控制代码的预处理或后处理,例如Quixote(https://www.mems-exchange.org/software/quixote/)及其对未分配给字符串的字面量的替代使用。变量将更容易支持。

虽然很少需要后者,但是前者是您需要担心支持的地方。在这里,您实际上可以重新定义文件系统交互API。由于某些人需要资产及其代码存储为文件,因此您需要提供一种读取文件,发现文件等的好方法。我们仍然需要实现API的这一部分,以发现可用的数据文件,列出它们等。 。

但是,您还需要特定于代码的API。正如Nick提到的,您最终需要API来发现包中包含的模块等,这些模块不是特定于文件的。具有API来处理模块的怪异的双重性是在其中您已经提取了文件的概念,但是随后您最终需要提供API来访问类似文件的资产数据。并且,一旦您尝试在另一个方面实现另一个以避免重复,则水域就会变得很模糊(即人们最终依赖预期的文件路径结构等,而没有注意到该路径可能不是真实路径)因为它用于包含代码的zip文件,而不仅仅是文件)。IOW您最终将不得不实现两个类似的API,但是从长远来看,您会更好。

正如Nick所说,我们的解决方案是一个很好的起点,但是如果我从头开始设计API,那不是我今天要做的。


-1

PEP 302允许您使用Python导入机制,这意味着您可以从其他来源(如数据库,zip文件等)导入代码。

在导入的Python实现中,有很长的复杂性历史,只有通过引入导入的Python实现才能简化。

我建议您仔细考虑一下极端情况。然后您可能会获得有用的实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.