python - 来自相关包的未知 python 导入行为

标签 python import

我偶然发现了一些奇怪的 python (2.7) 导入行为,虽然很容易解决,但让我摸不着头脑。

给定以下文件夹结构:

test/
    __init__.py
    x.py
    package/
        __init__.py
        x.py

其中 test/package/__init__.py 包含以下内容

from .. import x
print x
from .x import hello
print x
print x.hello

test/package/x.py 包含以下内容

hello = 1

为什么从 REPL 运行 import test.package 会产生以下输出?

<module 'test.x' from 'test/x.pyc'>
<module 'test.package.x' from 'test/package/x.pyc'>
1

我本希望 x 引用顶级 x 模块,但是第二个导入所做的是导入整个本地 x 模块(不仅仅是我预期的 hello),有效地践踏了第一次导入。

谁能解释一下这里的导入机制吗?

最佳答案

from .x import name 意识到 test.package.x 需要是一个模块。然后它检查 sys.modules 中的相应条目;如果在那里找到它,则 sys.modules['test.package.x'].hello 被导入到调用模块中。

但是,如果 sys.modules['test.package.x'] 尚不存在,则会加载该模块;并且加载 sys.modules['test.package'].x 的最后一步被设置为指向新加载的模块,即使您明确没有要求它。因此,第二个导入会覆盖第一个导入的名称。

这是设计使然,否则

import foo.bar.baz
foo.bar.baz.x()

from foo.bar import baz
baz.x() 

不可互换。


我无法在 Python 2 文档中找到有关此行为的良好文档,但是 Python 3 behaviour在这种情况下本质上是相同的:

When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in __import__()) a binding is placed in the parent module’s namespace to the submodule object. For example, if package spam has a submodule foo, after importing spam.foo, spam will have an attribute foo which is bound to the submodule.

[...]

The invariant holding is that if you have sys.modules['spam'] and sys.modules['spam.foo'] (as you would after the above import), the latter must appear as the foo attribute of the former.

关于python - 来自相关包的未知 python 导入行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29985574/

相关文章:

python - 生成包含另一个 NumPy 数组索引的 NumPy 数组

python - 在 Pandas 数据框中使用 NaN 条目折叠行

python - 在 SQL Server 中编写从备份创建数据库的脚本

webpack - 桶锉和树摇

python - PySpark:从另一个 Notebook 导入变量时,如何抑制 PySpark 单元中的 %run 输出?

css - 从外部目录导入 Sass 样式表

ASP.net 页面在导入语句上出现错误,但我确实有适当的引用?

python - 将 C++ 转换为 pyroot : How to get a file object from a file in pyroot?

python - 通过 Rauth OAuth 1.0 session 的多个请求

c# - 从文本文件读取多行固定宽度记录