是否可以制作一个上下文敏感的 python 上下文管理器来保存、修改和恢复状态?

发布于 2024-11-28 16:27:37 字数 828 浏览 2 评论 0原文

我有一对 python 函数,它们当前在两个值之间翻转全局变量。我想将它们变成上下文管理器,这样我就可以将它们用作 with 块,在块内设置变量,但之后恢复它。这是期望的行为:

>>> MODE
'user'
>>> mode_sudo()  # Sets MODE to 'sudo'...
>>> MODE
'sudo'
>>> mode_user()  # Sets MODE to 'user'...
>>> MODE
'user'
>>> with mode_sudo():
...    print MODE
'sudo'
>>> MODE
'user'

这样的嵌合体可能吗?

更新:为了清楚起见,这里是仅上下文管理器的实现:

from contextlib import contextmanager

@contextmanager
def mode_sudo():
    global MODE
    old_mode = MODE
    MODE = 'sudo'
    yield
    MODE = old_mode

@contextmanager
def mode_user():
    global MODE
    old_mode = MODE
    MODE = 'user'
    yield
    MODE = old_mode

使用关键字调用这些 w/oa 会返回一个生成器。有没有办法通过普通函数调用和巧克力上下文管理器来获得模式翻转行为?

I have a pair of python functions that currently flip a global variable between two values. I would like to turn them into context managers so I can use them as with blocks, setting the variable inside the block, but restoring it after. Here's the desired behaviour:

>>> MODE
'user'
>>> mode_sudo()  # Sets MODE to 'sudo'...
>>> MODE
'sudo'
>>> mode_user()  # Sets MODE to 'user'...
>>> MODE
'user'
>>> with mode_sudo():
...    print MODE
'sudo'
>>> MODE
'user'

Is such a chimera possible?

UPDATE: Just for clarity, here's the context-manager-only implementation:

from contextlib import contextmanager

@contextmanager
def mode_sudo():
    global MODE
    old_mode = MODE
    MODE = 'sudo'
    yield
    MODE = old_mode

@contextmanager
def mode_user():
    global MODE
    old_mode = MODE
    MODE = 'user'
    yield
    MODE = old_mode

Calling these w/o a with keyword returns a generator. Is there a way to get the mode-flipping behavior with both the plain-vanilla function call and the chocolate context manager?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你列表最软的妹 2024-12-05 16:27:37

这样做:

class mod_user:

    def __init__(self):
        global MODE
        self._old_mode = MODE
        MODE = "user"

    def __enter__(self):
        pass

    def __exit__(self, *args, **kws):
        global MODE
        MODE = self._old_mode

MODE = "sudo"

with mod_user():
    print MODE  # print : user.

print MODE  # print: sudo.

mod_user()
print MODE   # print: user.

Do it like this:

class mod_user:

    def __init__(self):
        global MODE
        self._old_mode = MODE
        MODE = "user"

    def __enter__(self):
        pass

    def __exit__(self, *args, **kws):
        global MODE
        MODE = self._old_mode

MODE = "sudo"

with mod_user():
    print MODE  # print : user.

print MODE  # print: sudo.

mod_user()
print MODE   # print: user.
天生の放荡 2024-12-05 16:27:37

简单的方法:

from contextlib import contextmanager
@contextmanager
def mode_user():
    global MODE
    old_mode = MODE
    MODE = "user"
    yield
    MODE = old_mode

同上 mode_sudo()。有关更多详细信息,请参阅文档。它实际上是整个“定义一个实现 __enter__ 和 __exit__ 的类”的快捷方式。

Easy way:

from contextlib import contextmanager
@contextmanager
def mode_user():
    global MODE
    old_mode = MODE
    MODE = "user"
    yield
    MODE = old_mode

idem for mode_sudo(). See the doc for more details. It is actually a shortcut for the whole "definine a class that implements __enter__ and __exit__"-thing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文