【问题标题】:Why __import__() is returning the package instead of the module?为什么 __import__() 返回的是包而不是模块?
【发布时间】:2013-03-05 02:13:27
【问题描述】:

我有这个文件结构(点是我的工作目录):

.
+-- testpack
     +-- __init__.py
     +-- testmod.py

如果我使用import 语句加载testmod 模块,我可以调用在其中声明的函数:

>>> import testpack.testmod
>>> testpack.testmod.testfun()
hello

但如果我尝试使用__import__() 函数做同样的事情,它就不起作用:

>>> __import__("testpack.testmod").testfun()

Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    __import__("testpack.testmod").testfun()
AttributeError: 'module' object has no attribute 'testfun'

确实,它返回的是包testpack,而不是模块testmod

>>> __import__("testpack.testmod").testmod.testfun()
hello

怎么会?

【问题讨论】:

  • 这并不能回答您的问题,但请注意 Python 3.1+ 有更好的方法来进行动态导入:importlib
  • @delnan:它在 2.7 中也可用。

标签: python module package python-import


【解决方案1】:

the docs 中给出了这种行为:

当 name 变量的格式为 package.module 时,通常 返回顶级包(直到第一个点的名称),而不是 按名称命名的模块。然而,当一个非空的 fromlist 参数 给定,则返回以名称命名的模块。

...

语句 import spam.ham 导致此调用:

spam = __import__('spam.ham', globals(), locals(), [], -1)

注意__import__() 如何在此处返回顶级模块,因为这是 由 import 语句绑定到名称的对象。

还要注意顶部的警告:

这是日常 Python 中不需要的高级功能 编程,不像importlib.import_module()

然后:

如果您只是想导入一个模块(可能在一个包中) 按名称,使用importlib.import_module()

所以这里的解决方案是使用importlib.import_module()

值得注意的是,Python 中名称两侧的双下划线表示手头的对象大部分时间都不能直接使用。就像您通常应该使用len(x) 而不是x.__len__()vars(x)/dir(x) 而不是x.__dict__。除非您知道为什么需要使用它,否则这通常表明有问题。

【讨论】:

    猜你喜欢
    • 2015-03-21
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 2010-12-16
    • 2014-04-09
    • 2015-11-02
    • 2021-09-13
    相关资源
    最近更新 更多