Python中如何通过字符串调用模块和函数?

8 投票
4 回答
2635 浏览
提问于 2025-04-16 21:13

通过字符串调用Python模块中的函数告诉我们如何使用getattr("bar")()来调用一个函数,但这假设我们已经导入了foo模块。

那么,如果我们想要执行"foo.bar",假设我们可能还需要导入foo(或者从bar导入foo),我们该怎么做呢?

4 个回答

1

这是我最终想出来的办法,用来从一个带点的名字中获取我想要的函数。

from string import join

def dotsplit(dottedname):
    module = join(dottedname.split('.')[:-1],'.')
    function = dottedname.split('.')[-1]
    return module, function

def load(dottedname):
    mod, func = dotsplit(dottedname)
    try:
        mod = __import__(mod, globals(), locals(), [func,], -1)
        return getattr(mod,func)
    except (ImportError, AttributeError):
        return dottedname
2

你可以使用 find_moduleload_module 这两个函数,它们来自 imp 模块,来加载在运行时确定名称和/或位置的模块。

文档最后的例子解释了具体怎么做:

import imp
import sys

def __import__(name, globals=None, locals=None, fromlist=None):
    # Fast path: see if the module has already been imported.
    try:
        return sys.modules[name]
    except KeyError:
        pass

    # If any of the following calls raises an exception,
    # there's a problem we can't handle -- let the caller handle it.

    fp, pathname, description = imp.find_module(name)

    try:
        return imp.load_module(name, fp, pathname, description)
    finally:
        # Since we may exit via an exception, close fp explicitly.
        if fp:
            fp.close()
3

使用 __import__(....) 函数:

http://docs.python.org/library/functions.html#import

(David 的理解差不多了,但我觉得他的例子更适合用来说明如果你想重新定义正常的导入过程该怎么做,比如从一个压缩文件中加载内容)

撰写回答