2015-05-26 20 views
1

我遵循以下约定来装饰Python类中的某些方法。我想知道是否有更好的方法来做同样的事情。我的方法当然不好看;原始成员函数的调用看起来并不直观。装饰Python类方法的最佳方法是什么?

from threading import Lock 

def decobj(fun): 
    def fun2(*args, **kwards): 
     with args[0].lock: 
      print 'Got the lock' 
      fun(*args, **kwards) 
    return fun2 

class A: 
    def __init__(self, a): 
     self.lock = Lock() 
     self.x = a 
     pass 

    @decobj 
    def fun(self, x, y): 
     print self.x, x, y 


a = A(100) 
a.fun(1,2) 
+1

*为什么*你觉得你的方法看起来不好?如果你只是装饰方法,为什么不直接向包装签名添加'self'? –

+1

@MartijnPieters对原始成员函数的调用看起来并不直观。所以,我认为会有更好的方法。 –

+0

如果你对Python的一元'*'和'**'运算符感到满意,它看起来很好。有些构造看起来很奇怪,直到你使用它们几次 – z0r

回答

2

如果你的装饰只能在方法的工作(因为你需要访问特定实例的锁),然后就包括在包装签名self

from functools import wraps 

def decobj(func): 
    @wraps(func) 
    def wrapper(self, *args, **kwards): 
     with self.lock: 
      print 'Got the lock' 
      func(self, *args, **kwards) 
    return wrapper 

我包括@functools.wraps() utility decorator;它会将各种元数据从原始包装函数复制到包装。这总是一个好主意。