首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python:如何创建并发安全的可重入上下文管理器,它在每个上下文中都是不同的。

Python:如何创建并发安全的可重入上下文管理器,它在每个上下文中都是不同的。
EN

Stack Overflow用户
提问于 2017-12-14 08:25:33
回答 1查看 501关注 0票数 4

我希望有一个对象conManager,它是一个可重入上下文管理器实例,每当我输入和退出它的上下文时,它都会打印一个数字,但是这个数字必须比previus上下文的数量高一个(从0开始)。

示例:

代码语言:javascript
复制
with conManager:
    print("Afirst")
    with conManager:
        print("Asecond")
        with conManager:
            print("third")
        print("Bsecond")
    print("Bfirst")

预期产出:

代码语言:javascript
复制
0
Afirst
1
Asecond
2
third
2
Bsecond
1
Bfirst
0

到目前为止,我唯一的解决方案是一个包含堆栈的类,但这并不是并发安全的。有没有什么并发安全的解决方案?

编辑:正如斯劳所指出的,当我的意思是并发安全时,我说线程安全,相应地改变了问题。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-14 10:20:11

我能想到的唯一解决方案是重写conManager的_call_,以便it返回一个上下文管理器,但我更愿意使用更干净的、不需要调用的用法。

编辑:既然其他人表现出了兴趣,我想我应该发布一个我找到的解决方案

代码语言:javascript
复制
from contextvars import ContextVar
from random import randrange
from weakref import WeakKeyDictionary

context_stack = ContextVar('context_stack')

class ReCm:
    def __init__(self):
        if not context_stack.get(None):
            context_stack.set(WeakKeyDictionary())
        context_stack.get()[self] = []
    def __enter__(self):
        v = randrange(10)
        context_stack.get()[self].append(v)
        print(f'entered {v}')
        return v
    def __exit__(self, exc_type, exc_val, exc_tb):
        v = context_stack.get()[self].pop()
        print(f'exited {v}')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47808851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档