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

Man*_*aux 3 python

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

test.py
testpkg/
        __init__.py
Run Code Online (Sandbox Code Playgroud)

test.py:

pkg = __import__("testpkg", fromlist=[''])
Run Code Online (Sandbox Code Playgroud)

__init__.py:

print "Called."
Run Code Online (Sandbox Code Playgroud)

打完电话后python test.py,调用.将被打印两次.为什么python执行__init__两次"模块"?

Gle*_*ard 5

这是一个Python bug.将空字符串作为元素传递fromlist是非法的,并且应该引发异常.

有没有必要包括""fromlist; 这是隐含的 - 模块本身总是被加载.实际发生的是module.submodule字符串使用空字符串,导致模块名称testpkg.,具有尾随句点.从字面上导入,因为它的名称不同testpkg,所以它作为单独的模块导入.

试试这个:

pkg = __import__("testpkg", fromlist=[''])
import sys
print sys["testpkg"]
print sys["testpkg."]
Run Code Online (Sandbox Code Playgroud)

......你会看到重复的模块.

如果还没有票,有人应该就此提交一张票; 太累了,不能自己做.


Bre*_*non 5

fromlist=['']python-dev明确不赞成使用hack导入特定模块.虽然它已被提交为一个问题,但它被修复的可能性很低,特别是因为这被视为fromlist开头的错误使用而不是必然的错误,并且可以获得更好的解决方案.

你应该做的是使用importlib.import_module(在Python 2.7和Python 3.1的标准库中提供,或者从PyPI兼容,兼容回到Python 2.3以及自1.1以来被包含在Django中django.utils.importlib).它将防止此问题发生,为导入模块提供更好的编程接口,甚至允许您在指定要导入的包时使用相对导入.

如果你真的不能使用importlib(例如,即使您可以通过PSF许可证自由复制的代码并且它相当短,也不允许PyPI依赖关系),那么您应该这样做__import__("some.module"); mod = sys.modules["some.module"].这是官方的,python-dev批准的问题解决方案(但只有你不能使用之后importlib).