2014-01-29 3 views
6

У меня есть функция f1 вручную:вызова декоратора, который принимает аргументы

def f1(): 
    return True 

У меня также есть декоратор, который принимает аргументы, которые могут быть использованы, как это:

@validate_arguments(arg1, arg2) 

Я пытаюсь вызовите f1 вручную без @ (для тестирования и повторного использования), но это, похоже, не работает.

Так что-то вроде:

validate_arguments(f1, arg1, arg2) 

Причина это не работает, потому что validate_arguments это функция, которая принимает аргументы в качестве параметров, и содержит замыкание, которое является фактическим декоратор.

Нет ли способа делать то, что я хочу? Чтобы вручную вызвать декоратор по функции без @, для декоратора, который принимает аргументы?

ответ

11

Вам нужно что-то вроде:

def f1(): 
    return True 
f1 = validate_arguments(arg1, arg2)(f1) 

validate_arguments(arg1, arg2) Здесь возвращает фактический декоратор, к этому декоратору мы передаем функцию объекта f1, который, в свою очередь, возвращает новую модифицированную функцию. не

Демо:

def validate_arguments(arg1, arg2): 
    def decorator(func): 
     def wrapped(): 
      print arg1, arg2 
      return func() 
     return wrapped 
    return decorator 

def f1(): 
    return True 
f1 = validate_arguments(1, 2)(f1) 
print f1() 
#1 2 
#True 
+0

Слегка связаны: если вы хотите, чтобы вызвать декоратор без прохождения в функции (например, декоратор выполняет свою работу в глобальном масштабе): 'the_decorator (лямбда: Нет) () ' – fgblomqvist

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