我的资源可以是需要锁定的R1类型,也可以是R2类型
不需要它:

class MyClass(object):   # broken
    def __init__ (self, ...):
        if ...:
            self.resource = R1(...)
            self.lock = threading.Lock()
        else:
            self.resource = R2(...)
            self.lock = None

    def foo(self):   # there are many locking methods
        with self.lock:
            operate(self.resource)


如果self.lockNone,则上述显然失败。

我的选择是:


if

def foo(self):
    if self.lock:
        with self.lock:
            operate(self.resource)
    else:
        operate(self.resource)



缺点:太冗长
优点:不会创建不必要的threading.Lock

始终将self.lock设置为threading.Lock


优点:代码简化
缺点:with self.lock似乎相对昂贵
(相当于磁盘I / O!)

定义一个简单的锁类:

class TrivialLock(object):
    def __enter__(self): pass
    def __exit__(self, _a, _b, _c): pass
    def acquire(self): pass
    def release(self): pass


并将其代替None用于R2


专家:简单代码
缺点:我必须定义TrivialLock



问题


社区首选哪种方法?
不管(1),实际上有人定义
TrivialLock? (我实际上希望这样的事情会
在标准库中...)
我的观察结果是锁定成本可与
write符合期望吗?

最佳答案

我将定义TrivialLock。但是,由于您只需要上下文管理器而不是锁,因此它甚至可能更琐碎。

class TrivialLock(object):
    def __enter__(self):
        pass
    def __exit__(*args):
        pass


您可以使用contextlib使其变得更简单:

import contextlib

@contextlib.contextmanager
def TrivialLock():
    yield

self.lock = TrivialLock()


并且由于yield可以是表达式,所以可以改为内联定义TrivalLock

self.lock = contextlib.contextmanager(lambda: (yield))()


注意括号; lambda: yield无效。但是,生成器表达式(yield)使它成为一次性上下文管理器。如果尝试在第二个with语句中使用相同的值,则会出现Runtime错误,因为generator已用尽。

关于python - Python中的琐碎上下文管理器,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48908085/

10-12 20:26