繁体   English   中英

Python:运行时动态创建function

[英]Python: dynamically create function at runtime

如何在Python中动态创建一个function?

我在这里看到了一些答案,但找不到可以描述最一般情况的答案。

考虑:

def a(x):
    return x + 1

如何即时创建这样的 function? 我必须compile('...', 'name', 'exec')它吗? 但那又怎样? 创建一个虚拟 function 并将其代码 object 替换为编译步骤中的那个?

或者我应该使用types.FunctionType吗? 如何?

我想自定义所有内容:参数的数量、它们的内容、function 正文中的代码、结果、...

使用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()

这对于将变量转换为常量很有用(“动态函数的模板变量”)

在我的例子中,我需要一个 function 返回 function 以将其保存到一个变量中:

def create_function(function_name, function_arguments, function_code):
    function_string = f"def {function_name}({function_arguments}): {function_code}"
    exec(function_string)
    return_value = eval(function_name)
    return return_value

name = 'say_hello'
arguments = 'name'
code = 'print(f"Hello, {name}!")'

myfunc = create_function(name, arguments, code)

print(myfunc, type(myfunc))
myfunc('John Doe')

为了完整起见,可以简单地参数化动态创建 function 的工作方式

def dynamically_create_greeting(greet_style):
    def inner(name):
        print(f'{greet_style} {name}')

    return inner


say_hello = dynamically_create_greeting(greet_style='hello')
say_hello('John')

say_hi = dynamically_create_greeting(greet_style='hi')
say_hi('John')

这会产生 output >

你好约翰

嗨,约翰

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM