Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
def mydecorator(fn) :
# здесь может быть какая-то полезная работа...
def wrapper(*args, **kwargs)
# ... или здесь что-то полезное ...
return fn(*args, **kwargs)
return wrapper
# зарегистрируем наш декоратор
mydecorator = dreg.decorator(mydecorator)
@dreg.decorator
def mydecorator( fn) :
# здесь может быть какая-то полезная работа...
def wrapper( *args, **kwargs)
# ... или здесь что-то полезное ...
return fn( *args, **kwargs)
return wrapper
class MyClass(object):
def my_method(self):
pass
class MyClass(object):
@one
def my_method(self):
pass
class MyClass(object):
@two
def my_method(self):
pass
class MyClass(object):
@one
@two
def my_method(self):
pass
class MyClass(object):
@two
@one
def my_method(self):
pass
def method(self):
return id(self)
class A(object):
id = method
class B(object):
id = method
A().id()
B().id()
method по вашему мнению?>>> def m():
... pass
...
>>> def m(self):
... pass
...
>>> class A(object):
... f = m
...
>>> class B(object):
... f = m
...
>>> A.f.im_class
<class '__main__.A'>
>>> B.f.im_class
<class '__main__.B'>
>>> m.im_class
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute 'im_class'
>>> def d( fn):
... print fn.im_class
... def w(*a, **k):
... return fn(*a, **k)
... return w
...
>>> class X(object):
... @d
... def f(self):
... pass
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in X
File "<stdin>", line 2, in d
AttributeError: 'function' object has no attribute 'im_class'
functools.wraps, случайно, не спасёт отца русской демократии ©? ;)def regular_dec(fn):
def wrapped(*args, **kwargs):
print 'regular decorator'
return fn(*args, **kwargs)
return wrapped
def method_dec(fn):
def wrapped(self, *args, **kwargs):
print 'method decorator. class is', type(self)
return fn(self, *args, **kwargs)
return wrapped
class A(object):
@regular_dec
@method_dec
def method1(self, some_arg=None):
print '>>> method1'
@method_dec
@regular_dec
def method2(self, some_arg=None):
print '>>> method2'
A().method1()
A().method2()
regular decorator
method decorator. class is <class '__main__.A'>
>>> method1
method decorator. class is <class '__main__.A'>
regular decorator
>>> method2
@route() корёжат переданные аргументы (*args, **kwargs) и что-то там ещё так, что «внешний» декоратор вообще не вызывается. Например такой код:def my_deco(fn):
def wrapped(*args, **kwargs):
print "HI"
#....
@my_deco
@route("/")
def index():
#...
@route("/", apply=[my_deco])
def index():
#...
@route("/", apply=[view("my_index_template"), my_beaker_cache])
def index():
return {
'data': some_data()
}
my_beaker_cache, закешировав отданный нами dict, а только потом вызовется шаблонизатор (и его никто кешировать не станет). Это может вызвать ошибки при отличии типа кеша от «memory» — в beaker сериализация идёт через json, который поддерживает ограниченное количество типов данных.@route("/abc")
@view("abcview")
def abc(db): # db - подключённая через Plugin база данных
# ...
Добавляем чуть больше рефлексии: декораторы