我有许多需要从各种导入文件中调用的函数。
这些功能按照以下方式形成:
a.foo
b.foo2
a.bar.foo4
a.c.d.foo5
并将它们作为原始字符串传递给我的脚本。
我正在寻找一种干净的方式来运行这些,带参数,并获得返回值
现在我有一个混乱的系统,分裂字符串,然后将它们送到正确的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)
答案 0 :(得分:1)
试试这个:
def lookup(path):
obj = globals()
for element in path.split('.'):
try:
obj = obj[element]
except KeyError:
obj = getattr(obj, element)
return obj
请注意,这将处理以任何全局名称开头的路径,而不仅仅是a
和b
导入的模块。如果对函数提供不受信任的输入存在任何可能的问题,则应该从包含允许的起始点的dict开始,而不是整个全局变量dict。
答案 1 :(得分:1)
很难从你的问题中看出来,但听起来你有一个命令行工具,你运行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)