2013-11-09 4 views
0

Если бы я хотел использовать декоратор следующим образом:Получение функции, определенная в функции с помощью декоратора

@getFunc('bar') 
def foo(): 
    def bar(): 
     print 'bar' 

Как бы я сделать декоратор получить внутреннюю функцию с именем бар?

def getFunc(str) 
    def getFunc_inner(func): 
     def new(*args, **kwargs): 
      func(*args, **kwargs) 
      myFunc = ??# Get function named {str} from func 
     return new 
    return getFunc_inner 
+0

Я думаю, что один из способов будет использовать '' inspect' и ast' модули. –

+0

короткий ответ: вы не можете – alko

+1

Возможный дубликат [Как получить/установить локальные переменные функции (извне) в Python?] (Http://stackoverflow.com/questions/1360721/how-to-get- set-local-variables-of-a-function-from-outside-in-python) – alko

ответ

0

вы можете вернуть функцию как это:

from functools import wraps 
def method_decorator(fn): 
    @wraps(fn) 
    def wrapper(*args, **kwargs): 
     res = fn(*args,**kwargs) 
     if callable(res): 
      return res() 
     return res 
    return wrapper 

@method_decorator 
def foo(*args, **kwargs): 
    def baz(): 
     return "foo" 
    return baz 

@method_decorator 
def bar(*args, **kwargs): 
    return("bar") 

if __name__ == "__main__": 
    print(foo()) 
    print(bar()) 

печатает:

foo 
bar 
0

декоратор не может, и не "получить" функцию. Декоратор - это функция, которая принимает функцию (украшенную функцию) и возвращает другую функцию (результат процесса декорирования).

Если обернутая функция должна была вернуть свою внутреннюю функцию, то функция, созданная декоратором, могла бы делать с ней что угодно.

Предоставленный объект функции, могу ли я получить функцию, определенную внутри этого объекта по имени?

Нет, поскольку оператор def является исполняемым. Вы смущены статическим внешним видом текста функции. Пока внешняя функция не будет вызвана, для доступа к ней нет внутреннего функционального объекта. Это обязательно так, так как объект внутренней функции закрывается над переменными (контекстом) вызова внешней функции. Или, говоря проще, в следующем коде две функции returned1 и returned2 различные функции:

def outer(x): 
    def inner(y): 
     return x+y 
    return inner 

returned1 = outer(2) 
returned2 = outer(2) 
+0

Тот факт, что это декоратор, на самом деле несущественен в этом случае. Я полагаю, что правильным вопросом было бы: Учитывая объект функции, могу ли я получить функцию, определенную внутри этого объекта по имени? Полагаю, я мог бы получить АСТ текста функции, но это кажется излишним. – grivescorbett

+0

@grivescorbett Это не имеет значения, если вы хотите полностью игнорировать все принципы стиля и дизайна. В любом случае, ответ на ваш вопрос заключается в том, что вы не можете. См. Мой отредактированный ответ. – Marcin