2012-07-02 3 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) 'breaks with' TypeError: '() не принимает никаких аргументов (1 задано)' ' –

+1

Просто потому, что ответ может быть неправильным, не означает, что это не дублирующий вопрос. –

ответ

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

Я просто попробовал, когда вы меняете вызов в конце с правильным nb аргументов, это segfault ... –

2

Как насчет этого подхода?

В этом примере я параметризирующую функции первого порядка по одной переменной (х -> ах + Ь) в одном классе:

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 ,

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 служит в качестве шаблона. Возвращаемое значение функции creator является функцией. После назначения вы используете my_new_function в качестве обычной функции.

Как правило, этот шаблон используется для декораторов функций, но также может быть полезен здесь.

0

Вы можете использовать лямбда для этого.

a=lambda x:x+1 
>>a(2) 
3 
Смежные вопросы