Я работаю над поиском способа уменьшить количество шаблонных декораторов. У нас есть много классов, которые используют @decorate. Например:
class MyClass(Base):
@decorate
def fun1(self):
pass
@decorate
def fun2(self):
pass
def fun3(self):
pass
Я хочу сделать так, чтобы по умолчанию там был декоратор, если кто-то не укажет иначе.
Я использую этот код для автоматического переноса
from functools import wraps
def myDecorator(func):
@wraps(func)
def decorator(self, *args, **kwargs):
try:
print 'enter'
ret = func(self, *args, **kwargs)
print 'leave'
except:
print 'exception'
ret = None
return ret
return decorator
class TestDecorateAllMeta(type):
def __new__(cls, name, bases, local):
for attr in local:
value = local[attr]
if callable(value):
local[attr] = myDecorator(value)
return type.__new__(cls, name, bases, local)
class TestClass(object):
__metaclass__ = TestDecorateAllMeta
def test_print2(self, val):
print val
def test_print(self, val):
print val
c = TestClass()
c.test_print1("print 1")
c.test_print2("print 2")
Мой вопрос:
- Есть ли лучший способ выполнить авто-декорирование?
- Как мне переопределить?
В идеале, мое конечное решение должно выглядеть примерно так:
class TestClass(object):
__metaclass__ = TestDecorateAllMeta
def autowrap(self):
print("Auto wrap")
@dont_decorate
def test_dont_decorate(self, val):
print val
Редактировать
Поговорить с одним из комментариев ниже, поскольку класс вызывается вместо выполнения
if callable(value):
Следует читать:
if isinstance(value,types.FunctionType)