python将decorator应用于类中的每个方法而不进行检查

时间:2012-08-09 21:19:17

标签: python class decorator metaclass

稍微修改Applying python decorators to methods in a class的答案,可以将装饰器应用于类中的每个方法。没有检查模块有没有办法做到这一点?我一直在尝试使用元类和修改__getattribute__来完成这个,但我不断得到无限递归。从How is the __getattribute__ method used?开始,可以使用object .__ getattribute __(self,name)在普通类中修复此问题。元类有什么相同的东西吗?

1 个答案:

答案 0 :(得分:3)

定义元类,然后在类定义的末尾应用装饰器。

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.

即可

但如果你真的不喜欢;我想使用检查而不是像你这样做

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