我在python中遇到了意外的导入行为,我不明白。希望你能帮助我澄清这种行为。假设有以下项目结构:
.
└── pkgimp
├── __init__.py
└── testing
├── __init__.py
├── mod_a.py
└── mod_b.py
以下源代码:
pkgimg / __初始化__吡啶:
import pkgimg.testing
pkgimg /检测/ __初始化__吡啶:
from mod_a import a
from mod_b import b # <- no import of c
pkgimg /检测/ mod_a.py :
a = 123
pkgimg /检测/ mod_b.py :
b = "foo"
c = "bar" # <- not imported
当我使用import pkgimp
导入包并使用dir(pkgimp.testing)
打印加载的模块时,我看到我没有导入的模块mod_a
和mod_b
?
这是我得到的:
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'a', 'b', 'mod_a', 'mod_b']
我假设只导入a
和b
,mod_a
和mod_b
此外,我可以访问从未在任何地方导入的c
。
>>> pkgimp.testing.mod_b.c
'bar'
我知道,如果将导入模块中的所有内容,将会对其进行评估。但是,我想,使用from M import x
只会给x
而不是整个模块!
例如,当我运行以下代码时:
>>> from pkgimp.testing.mod_b import b
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'b']
Python仅导入b,模块mod_b
。这就是我的预期。
答案 0 :(得分:1)
包中的模块一旦导入,就会始终作为包的属性添加。
因此,从任何其他模块导入pkgimp.testing.mod_b
时,mod_b
名称会添加到pkgimp.testing
。这是正常行为。
在上一个示例中,您将模块中的特定名称导入到本地名称空间中。如果您通过mod_b
检查sys.modules['pkgimp.testing.mod_b']
模块,您会发现仍然在该对象上定义了c
;将整个模块加载到内存中,并将b
的引用添加到本地命名空间。
在这种情况下,sys.modules['pkgimp.testing']
将具有mod_b
属性,该属性是对pkgimp.testing.mod_b
模块对象的引用。