Python2 反射:__import__() 的奇怪行为

Python2 reflection: Strange behavior of __import__()

我需要一个通用脚本,它将 some_module.function 作为参数并执行它。 我为此写了一个解决方案(必须 Python-2.4 兼容...):

def get_function(f_name):
    """Return function from library..."""
    lib, f = f_name.rsplit('.', 1)
    module = getattr(__import__(lib), lib.rsplit('.', 1)[-1])
    return getattr(module, f)

f = get_function('my_libs.testlib.test_function')
# finally, this executes the function
f()

我的问题是:

为什么我必须在 __import__() 之后执行 getattr()

原来 module = __import__('lib') 的命名空间 abovelib.

之一

所以当我想从 lib 调用一个函数时,比如 lib.f_x,我必须这样做:

module = __import__('lib')
module.lib.f_x()

而不是我所期望的:

module = __import__('lib')
module.f_x()

或者像上面那样使用 getattr() 的结构。 这是为什么?

the documentation -

When the name variable is of the form package.module , normally, the top-level package (the name up till the first dot) is returned, not the module named by name.

为什么?因为假设你要求它导入 blah.something ,应该返回的是 blah ,其中 somethingblah 中的一个属性(因此需要使用 getattr) .

一个简单的解决方案应该是 -

def get_function(f_name):
    """Return function from library..."""
    lib = f_name.rsplit('.', 1)[0]
    modl = __import__(lib)
    comps = f_name.split('.')[1:]
    for comp in comps:
        modl = getattr(modl,comp)
    return modl

如果您只是简单地导入模块,或者模块或包中的函数等,上述方法也适用。