2017-10-19 61 views
1

我有许多函数需要从各种导入的文件中调用。如何将字符串作为对象传递给getattr python

功能沿此线格式化:

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) 

回答

1

试试这个:

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

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

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) 
相关问题