__import __()调用__init__.py两次?

时间:2010-09-19 09:52:59

标签: python

我只是想知道为什么__import__()在加载包时会调用__init__模块两次。

test.py
testpkg/
        __init__.py

test.py

pkg = __import__("testpkg", fromlist=[''])

__init__.py

print "Called."

致电python test.py后,被叫。将被打印两次。为什么python执行__init__“模块”两次?

2 个答案:

答案 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)。