2010-10-13 79 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)