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

标签 python python-2.7 with-statement

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

相关文章:

c++ - 带有 C++ 语句的 Python

python - 在 python 中,一行中的多个 `with` 语句是否等同于嵌套的 `with` 语句?

python - Matplotlib 在刻度标签(字符串)中显示美元符号

python - 在 pandas 数据框中将日期转换为日期时间格式时出现问题

python - 无法为Python 2.7创建虚拟环境: setuptools fails with UnicodeEncodeError

python - 在文件中查找字符串的最快方法

python - 对 Python 中 try 和 with 的正确顺序感到困惑

Python 将简单整数列表转换为斐波那契数列

python - Django UserAdmin 的 add_fieldsets?

python - 带有权重的 numpy 数组部分和