导入包时出现意外行为

时间:2014-03-17 18:10:45

标签: python python-2.7 import

我在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_amod_b

这是我得到的:

['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'a', 'b', 'mod_a', 'mod_b']

我假设只导入abmod_amod_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。这就是我的预期。

1 个答案:

答案 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模块对象的引用。