2012-08-09 59 views
0

略有Applying python decorators to methods in a class修改答案,也可以將裝飾應用到一個類中的每個方法。沒有檢查模塊,有沒有辦法做到這一點?我一直在嘗試使用元類來完成這個工作,並修改__getattribute__,但我一直在獲取無限遞歸。從How is the __getattribute__ method used?,這可以使用object .__ getattribute __(self,name)在普通類中修復。元類有什麼相同之處嗎?蟒蛇應用於裝飾到每一個方法的類,而不檢查

回答

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.UnboundMethodTypetypes.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

注意:它不會裝飾靜態方法和類方法

+0

。在你的示例中沒有的元類。 – delnan 2012-08-09 21:27:56

+0

你確定它不會裝飾靜態方法嗎?因爲在提出這個問題之後,我發現了新方法,並且在靜態方法工作的地方寫了一些非常類似的東西。 – weeb 2012-08-09 21:43:28