[英]How to return a sub-function with variable arguments / exec() a definition inside another function ? (Python 3.x)
I have a foo
function that returns a value that is then used as input in a bar
function.我有一个
foo
function,它返回一个值,然后将其用作bar
function 中的输入。 In short, baz = bar(foo(•), •)
.简而言之,
baz = bar(foo(•), •)
。
Now, as I want to test multiple foo
iterations with a bar
that stays the same, I created the make_baz
function in order to return baz
depending on the iteration.现在,因为我想用一个保持不变的
bar
来测试多个foo
迭代,所以我创建了make_baz
function 以便根据迭代返回baz
。 (ie baz_i = bar(foo_i(•), •)
, etc.) (即
baz_i = bar(foo_i(•), •)
等)
The arguments and keywords are not always the same and I can not simply pass a dictionary as I am using scipy.optimize.curve_fit . arguments 和关键字并不总是相同的,我不能像使用scipy.optimize.curve_fit那样简单地传递字典。
I have found a way to theoretically do what I want (see below), but it seems I can not define a function with exec
inside another function (it works as expected while in global)..我找到了一种理论上做我想做的事情的方法(见下文),但似乎我无法在另一个 function 中定义一个带有
exec
的 function (它在全球范围内按预期工作)。
def foo_1(x, arg1, arg2, kwarg1=None):
y = "some function of x"
return y
def foo_2(x, arg1, kwarg1=None, kwarg2=None):
y = "some other function of x"
return y
def bar(y, bar_arg):
z = "function of y"
return z
def make_baz(foo):
args = list(inspect.signature(foo).parameters)
args_str = ", ".join(args)
kwargs_str = ", ".join([f"{arg}={arg}" for arg in args])
baz = f"def baz({args_str}, bar_arg):\n" \
f" y = {foo.__name__}({kwargs_str})\n" \
f" return bar(y=y, bar_arg=bar_arg)\n"
exec(baz)
return baz
print(make_baz(foo_1))
print(make_baz(foo_2))
Problem: it returns strings and not actual functions.问题:它返回字符串而不是实际函数。
"""
def baz(x, arg1, arg2, kwarg1, bar_arg):
y = foo(x=x, arg1=arg1, arg2=arg2, kwarg1=kwarg1)
return bar(y=y, bar_arg=bar_arg)
"""
"""
def baz(x, arg1, kwarg1, kwarg2, bar_arg):
y = foo(x=x, arg1=arg1, kwarg1=kwarg1, kwarg2=kwarg2)
return bar(y=y, bar_arg=bar_arg)
"""
Question: do you have any workaround/solution?问题:您有任何解决方法/解决方案吗?
The solution has been found on Behavior of exec function in Python 2 and Python 3 , defining loc = locals()
and adding it as a parameter for exec
:该解决方案已在 Python 2 和 Python 3 中的 exec function 的行为中找到,并将其定义
loc = locals()
exec
的参数:()
def make_baz(foo):
args = list(inspect.signature(foo).parameters)
args_str = ", ".join(args)
kwargs_str = ", ".join([f"{arg}={arg}" for arg in args])
baz = f"def baz({args_str}, bar_arg):\n" \
f" y = foo({kwargs_str})\n" \
f" return bar(y=y, bar_arg=bar_arg)\n"
loc = locals()
exec(baz, globals(), loc)
return loc["baz"]
EDIT: in order for the exec
to recognize bar
, we have to add globals()
as argument.编辑:为了让
exec
识别bar
,我们必须添加globals()
作为参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.