Леко модифициране на отговора от Прилагане на декоратори на Python към методи в клас е възможно да се приложи декоратор към всеки метод в клас. Има ли някакъв начин да направите това без модула за проверка? Опитвам се да постигна това с помощта на метакласове и модифициране на __getattribute__, но продължавам да получавам безкрайна рекурсия. От Как се използва методът __getattribute__?, това може да бъде коригирано в нормални класове с помощта на object.__getattribute__ (себе си, име). Има ли нещо еквивалентно за метакласове?
python прилага декоратор към всеки метод в клас без проверка
Отговори (1)
Дефинирайте мета клас и след това просто приложете декоратор в края на дефиницията на класа.
class Classname:
def foo(self): pass
for name, fn in inspect.getmembers(Classname):
if isinstance(fn, types.UnboundMethodType):
setattr(Classname, name, decorator(fn))
За Python 3 просто заменете types.UnboundMethodType
с types.FunctionType.
но ако наистина не искате да използвате inspect, можете да го направите по този начин
import types
class DecoMeta(type):
def __new__(cls, name, bases, attrs):
for attr_name, attr_value in attrs.iteritems():
if isinstance(attr_value, types.FunctionType):
attrs[attr_name] = cls.deco(attr_value)
return super(DecoMeta, cls).__new__(cls, name, bases, attrs)
@classmethod
def deco(cls, func):
def wrapper(*args, **kwargs):
print "before",func.func_name
func(*args, **kwargs)
print "after",func.func_name
return wrapper
class MyKlass(object):
__metaclass__ = DecoMeta
def func1(self):
pass
MyKlass().func1()
Изход:
преди func1
след func1
Забележка: няма да украси статичен метод и метод на клас
person
NIlesh Sharma
schedule
09.08.2012
сигурен ли си, че няма да украси статичния метод? защото след като зададох този въпрос, открих __new__ и написах нещо много подобно, където статичният метод работи.
- person weeb; 10.08.2012