2017-10-19 151 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) 
相關問題