我的资源可以是需要锁定的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
并将其代替
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/