Я видел много примеров декораторов Python, которые:
- декораторы стиля функции (обертывание функции)
- декораторы стиля класса (реализация
__init__
,__get__
и__call__
) - декораторы, которые не принимают аргументы
- декораторы, которые принимают аргументы
- декораторы, которые являются "дружественными к методу" (т.е. могут украсить метод в классе)
- декораторы, которые являются "дружественными к функциям" (могут украшать простую функцию
- декораторы, которые могут украшать как методы, так и функции
Но я никогда не видел ни одного примера, который мог бы сделать все вышеизложенное, и у меня возникли проблемы с синтезом из разных ответов на конкретные вопросы (например, этот, этот, или этот (который имеет один из лучших ответов, которые я когда-либо видел на SO)), как совместить все вышеперечисленное.
То, что я хочу, - это декоратор на основе класса, который может украсить либо метод, либо функцию, и , которая принимает хотя бы один дополнительный параметр. Т.е. так, что следующее будет работать:
class MyDecorator(object):
def __init__(self, fn, argument):
self.fn = fn
self.arg = argument
def __get__(self, ....):
# voodoo magic for handling distinction between method and function here
def __call__(self, *args, *kwargs):
print "In my decorator before call, with arg %s" % self.arg
self.fn(*args, **kwargs)
print "In my decorator after call, with arg %s" % self.arg
class Foo(object):
@MyDecorator("foo baby!")
def bar(self):
print "in bar!"
@MyDecorator("some other func!")
def some_other_function():
print "in some other function!"
some_other_function()
Foo().bar()
И я ожидаю увидеть:
In my decorator before call, with arg some other func!
in some other function!
In my decorator after call, with arg some other func!
In my decorator before call, with arg foo baby!
in bar!
In my decorator after call, with arg foo baby!
Изменить: если это имеет значение, я использую Python 2.7.