我的资源可以是需要锁定的 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
,上面的代码显然会失败。
我的选择是:
如果
:def foo(self): if self.lock: with self.lock: operate(self.resource) else: operate(self.resource)
- 缺点:太冗长
- pro:不会创建不必要的
threading.Lock
始终将
self.lock
设置为threading.Lock
- 优点:代码得到简化
- 缺点:
使用 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
问题
- 社区更喜欢哪种方法?
- 无论(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
语句中使用相同的值,则会收到 运行时
错误,因为生成器
已耗尽。
关于python - Python 中的简单上下文管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48908085/