如何将字符串作为对象传递给 getattr python

How to pass a string as an object to getattr python

我有许多函数需要从各种导入文件中调用。

函数的格式如下:

a.foo
b.foo2
a.bar.foo4
a.c.d.foo5

并且它们作为原始字符串传递到我的脚本中。

我正在寻找一种干净的方法 运行 这些,带参数,并获得 return 值

现在我有一个混乱的系统,可以拆分字符串然后将它们提供给正确的 getattr 调用,但这感觉有点笨拙并且非常不可扩展。有没有一种方法可以将 getattr 的对象部分作为字符串传递?或者其他一些方法?

import a, b, a.bar, a.c.d

if "." in raw_script:
    split_script = raw_script.split(".")
    if 'a' in raw_script:
        if 'a.bar' in raw_script:
            out = getattr(a.bar, split_script[-1])(args)
        if 'a.c.d' in raw_script:
            out = getattr(a.c.d, split_script[-1])(args)
        else:
            out = getattr(a, split_script[-1])(args)
    elif 'b' in raw_script:
        out = getattr(b, split_script[-1])(args)

试试这个:

def lookup(path):
    obj = globals()
    for element in path.split('.'):
        try:
            obj = obj[element]
        except KeyError:
            obj = getattr(obj, element)
    return obj

请注意,这将处理以任何全局名称开头的路径,而不仅仅是您的 ab 导入模块。如果对向函数提供不受信任的输入有任何可能的担忧,您应该从包含允许起点的字典开始,而不是整个全局字典。

很难从你的问题中判断出来,但听起来你有一个命令行工具你 运行 作为 my-tool <function> [options]。您可以像这样使用 importlib,避免大多数 getattr 调用:

import importlib

def run_function(name, args):
    module, function = name.rsplit('.', 1)
    module = importlib.import_module(module)
    function = getattr(module, function)
    function(*args)

if __name__ == '__main__':
    # Elided: retrieve function name and args from command line
    run_function(name, args)