[英]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.