0

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

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

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

>>> 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

怎么会?

4

1 回答 1

4

这种行为在文档中给出:

当 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)overx.__len__()vars(x)/ dir(x)over一样x.__dict__。除非您知道为什么需要使用它,否则这通常表明有问题。

于 2013-03-04T18:03:37.593 回答