Проверьте ответ Алекса, чтобы понять декораторы питона; кстати:
1) что вы не понимаете декораторов? Разве вы не понимаете декораторов как общую концепцию или декораторов Python? Опасайтесь, «классический» узор декоратора, аннотации java и декораторы питона - это разные вещи.
2) Декораторы python должны всегда возвращать функцию, например. в вашем коде возвращаемое значение param_checker ([...]) должно быть функцией, которая принимает функцию как параметр (func для оформления) и возвращает функцию с той же сигнатурой, что и my_decorated_function. Взгляните на следующий пример; функция декоратора выполняется только один раз (когда создается класс), тогда как украшенный func затем выполняется при каждом вызове. В этом конкретном примере он затем вызывает исходную функцию, но это не является обязательным требованием.
def decorator(orig_func):
print orig_func
def decorated(self, a):
print "aahahah", orig_func(self, a)
return decorated
class Example(object):
@decorator
def do_example(self, a):
return 2 * a
m = Example()
m.do_example(1)
3) вы, возможно, не делаете лучшего в том, как вы используете декораторы. Их обычно следует использовать, когда есть понятие, которое довольно ортогонально тому, что вы на самом деле программируете, и его можно использовать повторно - это, по сути, способ POPON для создания АОП.Ваш param_checker может быть не ортогональным - если ваш декоратор просто используется один раз, то, вероятно, это не очень хорошее место для использования декоратора. Кажется, ваш param_checker - это предполагает, что украшенный func принимает один аргумент, который является словарем, - есть ли в вашем коде много funcs с такой подписью и поведением? Если ответ «нет», просто проверьте параметры в начале func и вызовите исключение, если они отсутствуют.
Иногда я думаю, что у меня довольно хорошее понимание чего-то на Python, а затем Алекс * объясняет * это, и я понимаю, что я вдруг не понимаю его снова. Теперь мне придется провести медитацию на выходных на комбинате functools и bellybutton lint. –
@Peter, два других ответа объясняют аргументы, принимающие декораторы как классы, - принимая аргументы в '__init__', а затем функцию для украшения в' __call__'. Это тоже нормально, если реальная вещь (декоративные декораторы - функции, возвращающие функцию более высокого порядка - в частности: возврат функции, которая принимает функцию и возвращает функцию ;-) чувствует себя слишком странно ;-). Но приведенный выше пример действительно довольно прост (и 'functools.wraps' - просто аккуратное прикосновение, чтобы сохранить имя и docstring украшенной функции над будущей интроспекцией ...!). –
my_decorated_function = param_checker (['req_param_1', 'req_param_2']) (my_decorated_function). Я этого не понимаю. Что происходит, помещая украшенную функцию в parens после утверждения и как она реагирует на то, чтобы быть рядом с вызовом функции? – orokusaki