gpt4 book ai didi

python - from import ... in __init__.py 使模块名称可见?

转载 作者:太空狗 更新时间:2023-10-29 17:08:15 25 4
gpt4 key购买 nike

以下面的代码为例:

文件package1/__init__.py:

from moduleB import foo
print moduleB.__name__

文件package1/moduleB.py:

def foo(): pass

然后从当前目录:

>>> import package1
package1.moduleB

此代码适用于 CPython。令我惊讶的是 __init__.py 语句中的 from ... import 使 moduleB 名称可见。根据Python documentation ,这不应该是这样的:

The from form does not bind the module name

有人可以解释一下为什么 CPython 会那样工作吗?是否有任何文档对此进行详细描述?

最佳答案

文档误导了您,因为它描述了从包含它的父包外部导入模块的更常见情况。

例如,在我自己的代码中使用“from example import submodule”,其中“example”是一些与我自己的代码完全无关的第三方库,不绑定(bind)名称“example”。它仍然同时导入 example/__init__.py 和 example/submodule.py 模块,创建两个模块对象,并将 example.submodule 分配给第二个模块对象。

但是,子模块名称的“from..import”必须在父包对象上设置子模块属性。如果没有,请考虑:

  1. package/__init__.py 在导入包时执行。

  2. __init__ 执行“从子模块导入名称”。

  3. 稍后,其他完全不同的代码执行“import package.submodule”。

在第 3 步,要么 sys.modules["package.submodule"] 不存在,在这种情况下再次加载它会给你两个不同范围内的不同模块对象;或者 sys.modules["package.submodule"] 将存在,但“submodule”将不是父包对象 (sys.modules[“package”]) 的属性,并且“import package.submodule”将不执行任何操作。但是,如果它什么都不做,使用 import 的代码将无法访问作为包属性的子模块!


理论上,如果更改导入机制的其余部分以匹配,则可以更改导入子模块的工作方式。

如果您只需要知道从包 P 导入子模块 S 会做什么,那么简而言之:

  1. 确保导入 P,否则导入。 (此步骤递归处理“导入 A.B.C.D”。)
  2. 执行S.py 得到一个模块对象。 (跳过 .pyc 文件等细节)
  3. 在 sys.modules["P.S"] 中存储模块对象。
  4. setattr(sys.modules["P"], "S", sys.modules["P.S"])
  5. 如果该导入的形式为“import P.S”,则在本地范围内绑定(bind)“P”。

关于python - from <module> import ... in __init__.py 使模块名称可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6048786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com