类中的Python装饰器

时间:2018-03-02 02:21:44

标签: python multithreading locking decorator

我想用类变量制作装饰器。 如何使装饰器成为类功能? 因为我有很多需要锁定的功能。 我不想写下来

with self.lock: or self.lock.release() 

每个功能。 这是我的代码!

class Something:
    self.lock = Lock( .. )

    #decorator
    def _lock(self, func):
        def wrapper(*args, **kwargs):
            self.lock.acquire()
            func(*args, **kwargs)
            self.lock.release()
        return wrapper

    @_lock
    def some_func(self,):
        #do something

3 个答案:

答案 0 :(得分:2)

强烈建议如果您想要一种使用装饰器来简化线程锁定的方法,请使用synchronised包中的wrapt装饰器。

有关设计及其合理性的详细信息,请阅读以下内容。帖子中有太多细节可以在这里重复。

它允许的是:

@synchronized # lock bound to function1
def function1():
    pass

@synchronized # lock bound to function2
def function2():
    pass

@synchronized # lock bound to Class
class Class(object):

    @synchronized # lock bound to instance of Class
    def function_im(self):
        pass

    @synchronized # lock bound to Class
    @classmethod
    def function_cm(cls):
        pass

    @synchronized # lock bound to function_sm
    @staticmethod
    def function_sm():
        pass

要在类的方法中进行更细粒度的锁定,您也可以像上下文管理器一样使用它:

class Class(object):

    @synchronized
    def function_im_1(self):
        pass

    def function_im_2(self):
        with synchronized(self):
            pass

class Class(object):

    @synchronized
    @classmethod
    def function_cm(cls):
        pass

    def function_im(self):
        with synchronized(Class):
            pass

答案 1 :(得分:0)

你必须这样做。它只适用于实例方法,而不适用于函数。

class Something:
    self.lock = Lock( .. )

    #decorator
    def _lock(func):
        def wrapper(self, *args, **kwargs):
            self.lock.acquire()
            r = func(self, *args, **kwargs)
            self.lock.release()
            return r
        return wrapper

    @_lock
    def some_func(self):
        #do something

答案 2 :(得分:0)

类功能的含义对我来说不是很清楚。所以我在下面的代码中显示了两个不同的锁,一个用于类方法,另一个用于实例方法

我们需要在装饰器内调用func时使用def synchronized(func): """ Assumes that the first parameter of func has `_lock` property """ def wrapper(owner, *args, **kwargs): owner._lock.acquire() try: return func(owner, *args, **kwargs) finally: owner._lock.release() return wrapper class Something(object): _lock = Lock() # for class methods def __init__(self): self._lock = Lock() # for instance methods @synchronized def instance_method(self): print 'instance method invoked...' @classmethod @synchronized def class_method(cls): print 'class method invoked...'

{{1}}