Можно ли сделать контекстно-зависимый менеджер контекста 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
Вызов их без ключевого слова возвращает генератор. Есть ли способ получить поведение переключения режима с помощью вызова функции plain-vanilla и менеджера шоколадного контекста?
2 ответа
Сделай это так:
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.
Простой способ:
from contextlib import contextmanager
@contextmanager
def mode_user():
global MODE
old_mode = MODE
MODE = "user"
yield
MODE = old_mode
то же самое для mode_sudo()
, Смотрите документ для более подробной информации. Это на самом деле ярлык для всего "определить класс, который реализует __enter__
а также __exit__
"-вещь.