很抱歉的通用名称,将改变它,一旦我明白我的问题的根源,我有以下结构:
foo/
foo/__init__.py
foo/bar/
foo/bar/__init__.py
foo/bar/some_module.py
当我尝试这样做进口some_module:
from foo.bar import some_module
它的工作原理就像一个魅力。 但是,这是不适合我,因为我只知道在模块中运行时要导入的名称。 所以,如果我尝试:
from foo.bar import *
mod=__import__('some_module')
我得到一个错误。 难道我做错了什么? 有一个更好的方法吗? 为什么会出现这种情况?
这是为什么? 我不太确定我完全理解Python包背后的概念。 我以为他们是等同于Java的包,从而
我相信这样做的正确方法是:
mod = __import__('foo.bar', fromlist = ['some_module'])
这样,即使是“foo.bar”部分可以在运行时改变。 结果some_module
将作为mod.some_module
; 如果你想在一个单独的变量使用GETATTR:
the_module = getattr(mod, 'some_module')
from foo.bar import *
是一种不好的做法,因为它进口some_module
到全球范围。
您应该能够通过访问你的模块:
import foo.bar
mod = getattr(foo.bar, 'some_module')
它可以很容易地证明,这种方法的工作原理:
>>> import os.path
>>> getattr(os.path, 'basename')
<function basename at 0x00BBA468>
>>> getattr(os.path, 'basename\n')
Traceback (most recent call last):
File "<pyshell#31>", line 1, in <module>
getattr(os.path, 'basename\n')
AttributeError: 'module' object has no attribute 'basename
'
PS。如果您想继续使用你的那种import语句。 你需要一个eval
:
from foo.bar import *
eval('some_module')
为了澄清:它不仅是不好的做法是使用*
-导入,它甚至与组合更糟糕 eval
。 因此,只要使用getattr
,它的设计正是为像您这样的情况。
从文档 :
直接使用__import__()
是罕见的,除了要导入一个模块的名字只在运行时已知案例。
然而,点号应该工作:
mod = __import__('foo.bar.some_module')