如何在 Python 中动态创建函数?
我在这里看到了一些答案,但我找不到一个可以描述最一般情况的答案。
考虑:
def a(x):
return x + 1
如何即时创建这样的功能?我必须这样compile('...', 'name', 'exec')
做吗?但那又如何呢?从编译步骤创建一个虚拟函数并替换其代码对象?
还是我应该使用types.FunctionType
?如何?
我想自定义所有内容:参数的数量,它们的内容,函数体中的代码,结果,......
使用exec
:
>>> exec("""def a(x):
... return x+1""")
>>> a(2)
3
你看到了吗,这是一个告诉你如何使用的例子types.FunctionType
例子:
import types
def create_function(name, args):
def y(): pass
y_code = types.CodeType(args,
y.func_code.co_nlocals,
y.func_code.co_stacksize,
y.func_code.co_flags,
y.func_code.co_code,
y.func_code.co_consts,
y.func_code.co_names,
y.func_code.co_varnames,
y.func_code.co_filename,
name,
y.func_code.co_firstlineno,
y.func_code.co_lnotab)
return types.FunctionType(y_code, y.func_globals, name)
myfunc = create_function('myfunc', 3)
print repr(myfunc)
print myfunc.func_name
print myfunc.func_code.co_argcount
myfunc(1,2,3,4)
# TypeError: myfunc() takes exactly 3 arguments (4 given)
如果你需要从某个模板动态创建一个函数,试试这个:
def create_a_function(*args, **kwargs):
def function_template(*args, **kwargs):
pass
return function_template
my_new_function = create_a_function()
在函数create_a_function()中,您可以控制选择哪个模板。内部函数function_template用作模板。创建者函数的返回值是一个函数。分配后,您将my_new_function用作常规函数。
通常,此模式用于函数装饰器,但在这里也可能很方便。
您可以为此使用 lambda。
a = lambda x: x + 1
>>> a(2)
3
这种方法怎么样?
在这个例子中,我在一个类中对一个变量 (x -> ax+b)参数化一阶函数:
class Fun:
def __init__(self, a,b):
self.a, self.b = a,b
def f(self, x):
return (x*self.a + self.b)
u = Fun(2,3).f
这里 u
将是函数 x->2x+3。
你可以这样做:
new_func='def next_element(x):\n return x+1'
the_code=compile(new_func,'test','exec')
exec(the_code)
next_element(1)
它类似于以前的 exec 解决方案。
比 Berci 的答案更简单
def get_fn(a, b): # factory function
def fn(): # result function
print(a, b)
return fn
fn = get_fn(1, 2)
fn()
这对于将变量转换为常量很有用(“动态函数的模板变量”)