来自相关包的未知 python 导入行为
Unknown python import behaviour from relative package
我偶然发现了一些奇怪的 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 (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, theimport
orimport
-from
statements, or built-in__import__()
) a binding is placed in the parent module’s namespace to the submodule object. For example, if packagespam
has a submodulefoo
, after importingspam.foo
,spam
will have an attributefoo
which is bound to the submodule.[...]
The invariant holding is that if you have
sys.modules['spam']
andsys.modules['spam.foo']
(as you would after the above import), the latter must appear as thefoo
attribute of the former.