[英]Trivial context manager in Python
我的资源可以是需要锁定的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.lock
是None
则上述显然失败。
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
并为R2
使用它而不是None
。
TrivialLock
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
内联定义TrivalLock
:
self.lock = contextlib.contextmanager(lambda: (yield))()
注意括号; lambda: yield
无效。 但是,生成器表达式(yield)
使其成为一次性上下文管理器; 如果您尝试在第二个with
语句中使用相同的值,您将收到Runtime
错误,因为generator
已耗尽。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.