2012-07-02 56 views
24

Cách tạo động một hàm bằng Python?Python: tự động tạo hàm tại thời gian chạy

Tôi đã thấy một số câu trả lời ở đây nhưng tôi không thể tìm thấy câu trả lời nào mô tả trường hợp chung nhất.

xem xét:

def a(x): 
    return x + 1 

Làm thế nào để tạo ra chức năng như on-the-fly? Tôi có phải compile('...', 'name', 'exec') không? Nhưng những gì sau đó? Tạo một hàm giả và thay thế đối tượng mã của nó để sau đó một đối tượng từ bước biên dịch?

Hoặc tôi có nên sử dụng types.FunctionType không? Làm sao?

Tôi muốn tùy chỉnh tất cả mọi thứ: số lập luận, nội dung của họ, mã trong chức năng cơ thể, kết quả, ...

+3

thể trùng lặp của [chức năng động và vô danh Đúng thể bằng Python?] (Http://stackoverflow.com/questions/10303248/true-dynamic-and-anonymous-functions-possible-in-python) –

+0

Tôi không nghĩ rằng nó là một bản sao: 'dynf = FunctionType (biên dịch ('def f (x): return x + 3', 'dyn.py', 'exec'), globals())' và 'print dynf (1) 'ngắt với' LoạiError: '() không có đối số (1 đã cho)' ' –

+1

Chỉ vì câu trả lời có thể có sai không có nghĩa đây không phải là một câu hỏi trùng lặp. –

Trả lời

13

Sử dụng exec:

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

Bạn có thấy this, một mình ví dụ mà nói với bạn làm thế nào để sử dụng types.FunctionType

Ví dụ:

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

Vâng, tôi đã thấy nó và dường như đó chính xác là những gì tôi theo đuổi. Nhưng tôi không biết làm thế nào để tạo/sửa đổi chức năng cơ thể và trả về giá trị ..? –

+1

Tôi chỉ thử nó, khi bạn thay đổi cuộc gọi ở cuối với số nb chính xác của args, nó segfault ... –

2

Còn cách tiếp cận này thì sao?

Trong ví dụ này tôi parametrizing chức năng đặt hàng đầu tiên trên một biến (x -> ax + b) trong một lớp:

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 

đây u sẽ là chức năng x-> 2x + 3 .

7

Nếu bạn cần để tự động tạo một hàm từ một mẫu nhất định cố gắng mảnh này:

def create_a_function(*args, **kwargs): 

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

    return function_template 

my_new_function = create_a_function() 

Trong chức năng create_a_function() bạn có thể kiểm soát, trong đó mẫu để chọn. Hàm bên trong function_template đóng vai trò mẫu. Giá trị trả về của hàm tạo là một hàm. Sau khi chuyển nhượng, bạn sử dụng my_new_function làm chức năng thông thường.

Thông thường, mẫu này được sử dụng cho các trang trí chức năng, nhưng cũng có thể hữu ích ở đây.

0

Bạn có thể sử dụng lambda cho việc này.

a=lambda x:x+1 
>>a(2) 
3 
Các vấn đề liên quan