2015-02-26 4 views
4

I думаю ответ нет, но я не могу найти окончательное утверждение. У меня следующая ситуация;Украсить функцию после ее определения?

def decorated_function(function): 
    @functools.wraps(function) 
    def my_function(): 
     print "Hello %s" % function.__name__ 
    return my_function 

for attr, value in dct.iteritems(): 
    dct[attr] = decorated_function(value) 

И что я действительно хочу, это что-то типа;

def my_function(function): 
    print "Hello %s" % function.__name__ 

for attr, value in dct.iteritems(): 
    dct[attr] = functools.wraps(my_function, value) 

, чтобы удалить запутанную оболочку decor_function. Можно ли применять декораторы только при определении функции?

+2

Я не уверен, что вы здесь делаете. functools.wraps - это всего лишь небольшая утилита для копирования имен и атрибутов doc в декорированную функцию, она ничего не делает для изменения функциональности. Чего вы пытаетесь достичь? –

+1

Декораторы - это просто регулярные функции + синтаксический сахар, который позволяет удобно их применять, но последнее необязательно. Итак, ответ «да». – bereal

ответ

11

Вы можете украсить функции после того, как они определены. На самом деле, декораторы функций - это только синтаксический сахар. Например, вы можете заменить

@classmethod 
@synchronized(lock) 
def foo(cls): 
    pass 

с

def foo(cls): 
    pass 
foo = synchronized(lock)(foo) 
foo = classmethod(foo) 

См https://www.python.org/dev/peps/pep-0318/ подробности.

+0

Любые советы о том, как обращаться с 'UnboundLocalError: локальная переменная 'foo', на которую ссылаются перед присваиванием'? Например, функция, определенная на верхнем уровне, и декорированная версия объявляется в основном ?. - Редактируйте, кажется, что вы должны «глобально foo' линии раньше; это делает перегрузку назначения foo для всего этого пространства имен? - Редактировать Вы также можете назвать локальную версию soemthing else 'sync_foo = synchronized (foo)' – ThorSummoner

+1

Да, если вы объявите 'foo' global, он также изменит' foo' во всех других областях имен. Однако последнее предложение 'sync_foo', вероятно, является лучшей идеей: оно оставляет глобальное' foo' неизменным, и ваша локальная модифицированная версия явно отличается, чтобы избежать путаницы. –

Смежные вопросы