pypy 的导入钩子(自定义模块加载器)不起作用

Posted

技术标签:

【中文标题】pypy 的导入钩子(自定义模块加载器)不起作用【英文标题】:import hooks (custom module loaders) for pypy do not work 【发布时间】:2016-08-28 00:02:29 【问题描述】:

我成功地创建了导入钩子,以在 python2.7 中直接从内存中加载文件。我使用的示例是对这个问题的公认回答:

python:Import module from memory

但是;在 pypy 上应用此代码时;我收到导入错误。我还尝试了其他适用于常规 python 但不适用于 pypy 的导入钩子示例,例如:

python load zip with modules from memory

有谁知道为什么导入钩子在 pypy 中不起作用?有什么我遗漏的吗?

【问题讨论】:

【参考方案1】:

问题在于,在您指向的两个示例中,load_module() 都没有将加载的模块添加到sys.modules。通常,它应该这样做(然后 PyPy 像 CPython 一样工作)。

如果load_module() 没有将模块添加到sys.modules,那么每个import a 将再次调用load_module() 并返回模块的新副本。比如来自python:Import module from memory的例子:

import a as a1
import a as a2
print a1 is a2   # False!
a1.foo = "foo"
print a2.foo     # AttributeError

这在https://www.python.org/dev/peps/pep-0302/#id27 中有记录。 load_module() 方法负责进行比这些简单示例显示的更多的检查。特别要注意这一行(强调原文):

请注意,在加载器执行模块代码之前,模块对象必须在 sys.modules 中。

因此,在这种情况下,PyPy 的行为与 CPython 不同的事实可以理解为不遵守文档的代码导致的行为差异。

但无论如何,我的意见是应该修复它。我在https://bitbucket.org/pypy/pypy/issues/2382/sysmeta_path-not-working-like-cpythons 创建了一个问题。

【讨论】:

另外,请注意,您引用的两个示例在 CPython 3.x 中不起作用:它们在 File "<frozen importlib._bootstrap>" 内部的某个地方给您一个晦涩的 KeyError

以上是关于pypy 的导入钩子(自定义模块加载器)不起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义钩子获取后尝试访问数据不起作用

通过自定义注入器将服务注入动态生成的组件时,Angular ChangeDetection 不起作用

反应本机自定义组件道具不起作用

Firebase auth 和 React Hook - 从钩子返回函数不起作用

JVM进阶之自定义类加载器

JVM进阶之自定义类加载器