我只是想知道为什么__import__()
在加载包时会调用__init__
模块两次。
test.py
testpkg/
__init__.py
test.py
pkg = __import__("testpkg", fromlist=[''])
__init__.py
print "Called."
致电python test.py
后,被叫。将被打印两次。为什么python执行__init__
“模块”两次?
答案 0 :(得分:5)
这是一个Python错误。将空字符串作为fromlist
的元素传递是非法的,并且应该引发异常。
无需在""
中加入fromlist
;这是隐含的 - 模块本身总是被加载。实际发生的是module.submodule
字符串使用空字符串,导致模块名称testpkg.
,具有尾随句点。从字面上导入,因为它的名称与testpkg
不同,所以它作为单独的模块导入。
试试这个:
pkg = __import__("testpkg", fromlist=[''])
import sys
print sys["testpkg"]
print sys["testpkg."]
......你会看到重复的模块。
如果还没有人,应该提交一张票;现在我自己太累了。
答案 1 :(得分:5)
python-dev明确不赞成使用fromlist=['']
hack导入特定模块。虽然它已经filed as an issue,但它被修复的可能性很低,特别是因为这被认为是fromlist
的误用,而不是必然的错误,并且有更好的解决方案。< / p>
你应该做的是使用importlib.import_module
(可以在Python 2.7和Python 3.1的标准库中使用,或者从PyPI兼容,返回到Python 2.3,并且从1.1开始包含在Django中{{1} })。它将防止此问题发生,为导入模块提供更好的编程接口,甚至允许您在指定要导入的包时使用相对导入。
如果真的无法使用importlib(例如,即使您可以通过PSF许可证自由复制的代码并且它相当短,也不允许PyPI依赖项),那么您应该{ {1}}。这是官方的,python-dev批准的问题解决方案(但只有 之后才能使用django.utils.importlib
)。