可以创建一个上下文敏感的Python上下文管理器来保存、修改和恢复状态吗?
我有一对 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
如果不使用 with
关键字来调用这些函数,它们会返回一个生成器。有没有办法让这两个函数在普通调用和上下文管理器中都能实现切换模式的效果呢?
2 个回答
2
简单的方法:
from contextlib import contextmanager
@contextmanager
def mode_user():
global MODE
old_mode = MODE
MODE = "user"
yield
MODE = old_mode
对于 mode_sudo()
也是一样的。想了解更多细节,可以查看 这个文档。其实这就是一个简化的方式,用来代替“定义一个实现了 __enter__
和 __exit__
的类”的复杂过程。
8
这样做:
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.