我正在传递字符串列表,我想使用 functools.partial 将其转换为方法调用:
[ 'object1.method1(arg1, arg2, 4, key=value)', 'object2.method2(6, arg1)' ...]
使用正则表达式生成 functools.partial 所需的“func”参数很容易,但是我很容易将括号内的字符串转换为有效的 *args 和 **kwargs 来传递给functools.partial。
每个列表项都保证是有效的 Python。我只是无法想出一种快速、简单的方法来将“arg1、arg2、4、key=value”等字符串转换为 functools.partial 可以使用的东西。我错过了什么?
更新:
我很抱歉。我确实忘记了重要信息。 args 不是此过程范围内的有效标识符,因此“eval”不起作用。然而,它们在使用结果部分对象的范围内是正确的,因此它们可以作为文字“复制”。 我当前的过程返回一个字符串“arg1,arg2,4,this=that”。如果直接传递给 functools.partial,functools.partial 会将其“包装”为单个字符串参数。
嗯..我描述得越多,我就越意识到除非这些标识符在此范围内有效,否则无法做到这一点...
最佳答案
我正在写另一个答案,因为如果我更改旧的答案,评论将根本无法反射(reflect)内容。相反,如果事实证明这是一个更好的答案,我将撤回另一个答案。以下内容应该有效。
工作原理:
- 获取你的函数
- 解析参数字符串
- 将每个参数及其自身的 eval 放在一个部分中
- 将包装器、func 和部分参数放入部分
- 在需要的范围内执行
下面的代码集中在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)
关于python - 从解析的字符串创建 functools.partial *args 和 *kwargs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3920043/