2012-07-02 65 views
24

如何在Python中動態創建函數?Python:在運行時動態創建函數

我在這裏看到了一些答案,但我找不到一個可以描述最一般情況的答案。

考慮:

def a(x): 
    return x + 1 

如何在即時創建這樣的功能?我必須compile('...', 'name', 'exec')嗎?但是呢?創建一個虛擬函數並從編譯步驟中替換它的代碼對象?

或者我應該使用types.FunctionType?怎麼樣?

我想定製一切:參數的數量,它們的內容,在函數體,結果,代碼...

+3

的可能重複的[真動態和匿名可能在Python函數?](http://stackoverflow.com/questions/10303248/true-dynamic-and-anonymous-functions-possible-in-python) –

+0

我不認爲它是重複的:'dynf = FunctionType(compile('def f(x):return x + 3','dyn.py','exec'),globals())''和print dynf 1)'TypeError':'()不帶參數(1給出)'' –

+1

'因爲答案可能有錯並不意味着這不是一個重複的問題。 –

回答

13

使用exec

>>> exec("""def a(x): 
... return x+1""") 
>>> a(2) 
3 
9

你看到this,它的例如,它告訴你如何使用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) 
+2

是的,我看到它,它似乎正是我所追求的。但我不知道如何創建/修改函數體和返回值..? –

+1

我剛試了一下,當你改變了調用結尾的正確數目的參數,它segfault ... –

2

這種方法呢?

在這個例子中我參數化一階函數對一個變量(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-> 2×3 + 。

7

如果您需要動態地創建從一定的樣板函數嘗試這片:

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作爲常規功能。

通常情況下,這個模式用於函數裝飾器,但也可以在這裏使用。

0

您可以使用lambda來做到這一點。

a=lambda x:x+1 
>>a(2) 
3