gpt4 book ai didi

python - Python 中的简单上下文管理器

转载 作者:太空宇宙 更新时间:2023-11-03 14:05:43 28 4
gpt4 key购买 nike

我的资源可以是需要锁定的 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,上面的代码显然会失败。

我的选择是:

  1. 如果:

    def foo(self):
    if self.lock:
    with self.lock:
    operate(self.resource)
    else:
    operate(self.resource)
    • 缺点:太冗长
    • pro:不会创建不必要的threading.Lock
  2. 始终将 self.lock 设置为 threading.Lock

    • 优点:代码得到简化
    • 缺点:使用 self.lock 似乎相对昂贵(与磁盘 I/O 相当!)
  3. 定义一个简单的锁类:

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

    并使用它来代替 R2None

    • 优点:简单的代码
    • 缺点:我必须定义 TrivialLock

问题

  1. 社区更喜欢哪种方法?
  2. 无论(1)如何,是否有人真正定义了类似的东西TrivialLock? (我实际上预计类似的事情会是在标准库中...)
  3. 据我观察,锁定成本与锁定成本相当吗?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/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com