gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-30 00:04:38 24 4
gpt4 key购买 nike


背景

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

该类目前为我们节省了很多潜在死锁的麻烦,因为我们可以在 RAII style 中调用它。 ,即:

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?我们希望将所有这些功能保留在一个类中。

谢谢。

最佳答案

是的,你可以得到这个接口(interface)。将在 with 语句的上下文中进入/退出的对象是已解析的属性。因此,您可以继续将上下文管理器定义为上下文管理器的属性:

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

关于python - 在python中调用上下文管理器的多种方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53546824/

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