在python中调用上下文管理器的多种方法

云 :

背景

我在python中有一个接受互斥体列表的类。然后,它将对该列表进行排序,并使用__enter__()__exit__()以特定顺序锁定/解锁所有互斥锁,以防止死锁。

当前,该类为我们节省了很多潜在的死锁麻烦,因为我们只能以RAII样式调用它,即:

self.lock = SuperLock(list_of_locks)
# Lock all mutexes.
with self.lock:
    # Issue calls to all hardware protected by these locks.

问题

我们想公开此类提供RAII样式的API的方法,以便在以某种方式调用时,一次只能锁定一半的互斥锁,即:

self.lock = SuperLock(list_of_locks)
# Lock all mutexes.
with self.lock:
    # Issue calls to all hardware protected by these locks.

# Lock the first half of the mutexes in SuperLock.list_of_locks
with self.lock.first_half_only:
    # Issue calls to all hardware protected by these locks.

# Lock the second half of the mutexes in SuperLock.list_of_locks
with self.lock.second_half_only:
    # Issue calls to all hardware protected by these locks.

有没有办法提供这种类型的功能,以便我可以调用with self.lock.first_half_onlywith self.lock_first_half_only()向用户提供简单的API?我们希望将所有这些功能都放在一个类中。

谢谢。

威姆:

是的,您可以获取此界面。在with语句的上下文中将要输入/退出的对象是resolve属性。因此,您可以继续将上下文管理器定义为上下文管理器的属性:

from contextlib import ExitStack  # pip install contextlib2
from contextlib import contextmanager

@contextmanager
def lock(name):
    print("entering lock {}".format(name))
    yield
    print("exiting lock {}".format(name))

@contextmanager
def many(contexts):
    with ExitStack() as stack:
        for cm in contexts:
            stack.enter_context(cm)
        yield

class SuperLock(object):

    def __init__(self, list_of_locks):
        self.list_of_locks = list_of_locks

    def __enter__(self):
        # implement for entering the `with self.lock:` use case
        return self

    def __exit__(self, exce_type, exc_value, traceback):
        pass

    @property
    def first_half_only(self):
        return many(self.list_of_locks[:4])

    @property
    def second_half_only(self):
        # yo dawg, we herd you like with-statements
        return many(self.list_of_locks[4:])

创建并返回新的上下文管理器时,可以使用实例中的状态(即self)。

用法示例:

>>> list_of_locks = [lock(i) for i in range(8)] 
>>> super_lock = SuperLock(list_of_locks) 
>>> with super_lock.first_half_only: 
...     print('indented') 
...   
entering lock 0
entering lock 1
entering lock 2
entering lock 3
indented
exiting lock 3
exiting lock 2
exiting lock 1
exiting lock 0

编辑lock上面显示生成器上下文管理器的基于类的等效项

class lock(object):

    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print("entering lock {}".format(self.name))
        return self

    def __exit__(self, exce_type, exc_value, traceback):
        print("exiting lock {}".format(self.name))
        # If you want to handle the exception (if any), you may use the
        # return value of this method to suppress re-raising error on exit

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Python类型提示和上下文管理器

异步上下文管理器

Python多行嵌套上下文管理器

在上下文管理器中处理异常

在python中,在安装/拆卸中使用上下文管理器有一个很好的习惯用法

在python中,在设置/拆卸中使用上下文管理器有一个很好的习惯用法

Python:模拟上下文管理器

Python:模拟上下文管理器

在Python2.7上下文管理器类中处理异常的正确方法

Python 3 urlopen上下文管理器模拟

Python:使用上下文管理器临时更改随机种子的危险?

测量时间的Python上下文管理器

Python:标准函数和上下文管理器?

使用上下文管理器作为功能

停止python进程,以便上下文管理器仍调用__exit __(在Windows中)

Python中的琐碎上下文管理器

使用上下文管理器管理多种资源的正确方法

Python中是否有一种方法可以手动退出“ with”语句(上下文管理器)

在python中调用上下文管理器

python上下文管理器不传递异常

如何使用上下文管理器以原子方式(退出时)在列表中附加值?

如何使 python 类成为上下文管理器

是否使用上下文管理器?

如何在不使用上下文管理器的情况下避免在 Locust 中记录请求?

如何使用上下文管理器锁定

在 python 中使用上下文管理器超时进程

Python 上下文管理器

垃圾回收期间无法调用 on_state_changed,请务必关闭或使用上下文管理器

如何使用上下文管理器将每个方法包装在一个类中?