簡體   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