2010-10-13 160 views
1

我傳遞,我想轉換到方法的字符串列表創建functools.partial * ARGS&* kwargs呼叫使用functools.partial:從解析字符串

[ 'object1.method1(arg1, arg2, 4, key=value)', 'object2.method2(6, arg1)' ...] 

可以很容易地使用正則表達式來爲functools.partial生成必要的'func'參數,但我有一段時間很容易將parens中的字符串轉換爲有效的* args和** kwargs傳遞給functools.partial。

每個列表項都保證是有效的Python。我只是無法想出一個快速,簡單的方法來將諸如'arg1,arg2,4,key = value'之類的字符串轉換爲functools.partial可以使用的某些東西。我錯過了什麼?

更新:

我的appologies。我沒有忘記重要的信息。這個參數在這個過程的範圍內不是有效的標識符,因此'eval'不起作用。但是,它們在所使用的部分對象的範圍內是正確的,因此它們可以作爲文字「複製」。 我當前的過程返回一個字符串'arg1,arg2,4,this = that'。如果直接傳遞給functools.partial,則functools.partial會將其作爲單個字符串參數「包裝」。

嗯..我就越說明這一點,我越來越意識到,有沒有辦法做到這一點,除非這些標識符此範圍內有效......

+0

由於這些都是爲泛音,都是「ARG1」,「ARG2」等將在後面提供用於值的佔位符,而不是文字「4」和「6」的是大概將在創建中使用部分?什麼是用於部分的命名參數的佔位符與文字的語法? 「object1」是一個佔位符嗎?也許如果你展示了之前和之後的情況 - 「對於'blah',我會創建這個部分」。 – PaulMcG 2010-10-13 00:52:23

+0

哪裏定義了object1,arg1,arg2,object2等?即範圍。它們是在locals()或globals()中定義的,還是你在創建functools.partial函數的地方定義的? eval是一個可行的選擇嗎? – snapshoe 2010-10-13 03:35:34

回答

2

我正在寫另一個答案,因爲如果我改變舊的,評論不會反映內容。相反,如果這是一個更好的答案,我會撤回另一個。以下應該工作。

操作原理的:

  1. 獲取您的FUNC
  2. 的參數
  3. 把每一個參數連同其自身的eval在部分
  4. 解剖串放在一個包裝,FUNC和部分」在部分
  5. d參數執行在所需要的範圍

以下代碼集中在2.-4。進口是假定的。當然有,因爲在範圍


def wrapper(func_, *args, **kw): 
    new_args = [] 
    new_kw = {} 
    for arg in args: 
     if type(arg)==functools.partial: 
      arg = arg() 
     new_args.append(arg) 
    for key in kw: 
     value = kw[key] 
     if type(value)==functools.partial: 
      value = value() 
     new_kw[key]=value 
    return func_(*new_args, **new_kw) 

orig_str = 'object1.method1(arg1, arg2, 4, key=value)' 
argstr = re.search('.+\((.+)\)', orig_str).group(1) 
args = [] 
kw = {} 
for x in argstr.split(','): 
    if '=' in x: 
     key, value = x.strip().split('=') 
    else: 
     value = x.strip() 
     key = None    
    value = functools.partial(eval, value) 
    if key: 
     kw[key]=value 
    else: 
     args.append(value) 

what_you_want = functools.partial(wrapper, func, *args, **kw) 
+0

我喜歡你的概念,在執行時對它們進行評估的參數周圍放置一個包裝 - 假設它們將在那裏定義。我將這個標記爲答案,但我建議未來的讀者將他們視爲僞代碼。謝謝,Knitti。好想法! – 2010-10-14 18:25:21

0

易於使用足夠eval函數和一個自定義的,沒有必然的正則表達式替換函數名額外的代碼名稱碰撞的另外一個問題。

def get_args_and_kwargs(*args, **kwargs): 
    return args, kwargs 

def convert_str_to_args_and_kwargs(s): 
    return eval(s.replace(s[:s.find('(')], 'get_args_and_kwargs')) 

for s in your_list: 
    args, kwargs = convert_str_to_args_and_kwargs(s)