python和__import__的问题

时间:2009-08-27 16:12:05

标签: python import

对于通用标题感到抱歉,一旦我理解了问题的根源,就会更改它 我有以下结构:

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的包,因此

3 个答案:

答案 0 :(得分:7)

我认为正确的方法是:

mod = __import__('foo.bar', fromlist = ['some_module'])

这样甚至'foo.bar'部分也可以在运行时更改。 因此,some_module将以mod.some_module的形式提供;如果你想在一个单独的变量中使用getattr:

the_module = getattr(mod, 'some_module')

答案 1 :(得分:1)

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
'

P.S。如果您仍然对使用您的导入声明感兴趣。您需要eval

from foo.bar import *
eval('some_module')

澄清一下:不仅使用*是不好的做法 - 将其导入甚至更差并与eval结合使用。所以只需使用getattr,它就像你的情况一样专门设计。

答案 2 :(得分:0)

来自docs

  

直接使用__import__()的情况很少见,除非您要导入名称仅在运行时已知的模块。

然而,点缀符号应该有效:

mod = __import__('foo.bar.some_module')