Немного изменив ответ из Применение декораторов Python к методам в классе, можно применить декоратор к каждому методу в классе. Есть ли способ сделать это без модуля проверки? Я пытался добиться этого, используя метаклассы и изменяя __getattribute__, но продолжаю получать бесконечную рекурсию. Из Как используется метод __getattribute__?, это можно исправить в обычных классах с помощью объекта .__ 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
Примечание: он не украшает staticmethod и classmethod
person
NIlesh Sharma
schedule
09.08.2012
вы уверены, что это не украсит статический метод? потому что, задав этот вопрос, я обнаружил __new__ и написал нечто очень похожее, где работал статический метод.
- person weeb; 10.08.2012