来自相对包的未知python导入行为
我偶然发现了一些奇怪的python(2.7)导入行为,虽然很容易解决,但让我摸不着头脑 给定以下文件夹结构:来自相对包的未知python导入行为,python,import,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 hello = 1 test/
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
hello = 1
test/package/x.py包含以下内容
from .. import x
print x
from .x import hello
print x
print x.hello
hello = 1
为什么从REPL运行import test.package
会导致以下输出
<module 'test.x' from 'test/x.pyc'>
<module 'test.package.x' from 'test/package/x.pyc'>
1
1.
我本来希望x
引用顶级x
模块,但是第二次导入所做的是导入整个本地x
模块(而不是像我预期的那样仅导入hello
),实际上是对第一次导入的践踏
有人能在这里解释导入的机制吗?来自.x导入名称的
意识到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()
及
不能互换
我无法在Python 2文档中找到关于此行为的良好文档,但在本例中基本相同:
当使用任何机制(例如importlib
API、import
或import
--from
语句或内置的\uu import\uuu()
)加载子模块时,会在父模块的命名空间中放置到子模块对象的绑定。例如,如果包spam
具有子模块foo
,则导入spam.foo
后,spam
将具有绑定到子模块的属性foo
[……]
不变的保持是,如果您有sys.modules['spam']
和sys.modules['spam.foo']
(正如您在上述导入之后所做的那样),则后者必须显示为前者的foo
属性
是什么让你认为第一次导入带来了一个x
,第二次导入用另一个x
?在你的代码或描述中没有任何东西可以测试或演示这一点right@AnttiHaapala他可能是,但他没有实际测试(例如,在第二次导入之前和之后通过print x
)可能重复的abarnert,当我更改代码以在第二次导入之前添加打印时,它会首先突出显示导入的预期模块:其次: