Python:在运行时动态创建函数

Eci*_*ana 37 python runtime function

如何在Python中动态创建函数?

我在这里看到了一些答案,但我找不到一个可以描述最常见情况的答案.

考虑:

def a(x):
    return x + 1
Run Code Online (Sandbox Code Playgroud)

如何即时创建这样的功能?我需要compile('...', 'name', 'exec')吗?那么呢?从编译步骤创建一个虚函数并替换它的代码对象?

或者我应该使用types.FunctionType?怎么样?

我想自定义一切:参数的数量,它们的内容,函数体中的代码,结果,...

mav*_*ato 22

用途exec:

>>> exec("""def a(x):
...   return x+1""")
>>> a(2)
3
Run Code Online (Sandbox Code Playgroud)

  • 如果有人得到 `NameError` 考虑使用 `locals().get('a') (2认同)

Ahs*_*san 22

你有没有看到这个,它是一个告诉你如何使用的例子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)
Run Code Online (Sandbox Code Playgroud)

  • 是的,我看到它,它似乎正是我所追求的.但我不知道如何创建/修改函数体和返回值..? (2认同)
  • 我只是尝试了一下,当您在末尾使用正确的args更改调用时,它会出现段错误... (2认同)

小智 13

如果您需要从某个模板动态创建一个函数,请试试这个:

def create_a_function(*args, **kwargs):

    def function_template(*args, **kwargs):
        pass

    return function_template

my_new_function = create_a_function()
Run Code Online (Sandbox Code Playgroud)

在函数create_a_function()中,您可以控制选择哪个模板.内部函数function_template用作模板.创建者函数的返回值是一个函数.分配后,使用my_new_function作为常规函数.

通常,此模式用于函数装饰器,但也可以在此处使用.

  • 它有一些限制,不能通过pickle序列化 (2认同)

Ber*_*rci 9

这种方法怎么样?

在此示例中,我在一个类中的一个变量 (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
Run Code Online (Sandbox Code Playgroud)

这里 u 将是函数 x->2x+3。


vis*_*m c 5

您可以为此使用lambda。

a = lambda x: x + 1
>>> a(2)
3
Run Code Online (Sandbox Code Playgroud)

  • 我现在用的几乎就是这个。就我而言,我需要动态地将函数构建为字符串或预编译配置的字符串表达式,因此我使用了 `a = eval("lambda x: x + 1")` 代替,但结果是相同的。就我而言,我还为表达式提供数学函数,因此我还在计算和执行 lambda 的 python 脚本中添加了“from math import *”。 (2认同)

Hel*_*ior 5

你可以这样做:

new_func='def next_element(x):\n  return x+1'
the_code=compile(new_func,'test','exec')
exec(the_code)
next_element(1)
Run Code Online (Sandbox Code Playgroud)

它类似于之前的 exec 解决方案。