Python 3.4 предоставляет этот удобный инструмент для временного перенаправления stdout:
# From https://docs.python.org/3.4/library/contextlib.html#contextlib.redirect_stdout
with redirect_stdout(sys.stderr):
help(pow)
Код не очень сложен, но я бы не стал хочется писать его снова и снова, тем более, что в него вложена некоторая мысль, чтобы сделать его повторно:
class redirect_stdout:
def __init__(self, new_target):
self._new_target = new_target
# We use a list of old targets to make this CM re-entrant
self._old_targets = []
def __enter__(self):
self._old_targets.append(sys.stdout)
sys.stdout = self._new_target
return self._new_target
def __exit__(self, exctype, excinst, exctb):
sys.stdout = self._old_targets.pop()
Мне интересно, есть ли общий способ использования оператора with
для временного изменения значения переменной. Два других варианта использования из sys
— это sys.stderr
и sys.excepthook
.
В идеальном мире сработало бы что-то вроде этого:
foo = 10
with 20 as foo:
print(foo) # 20
print (foo) # 10
Я сомневаюсь, что мы сможем это сделать, но, возможно, что-то вроде этого возможно:
foo = 10
with temporary_set('foo', 20):
print(foo) # 20
print (foo) # 10
Я могу заставить это работать, копаясь в globals()
, но никто не захочет использовать это.
ОБНОВЛЕНИЕ: хотя я думаю, что мои примеры «foo = 10» прояснили, что я пытаюсь сделать, они не передают реальный вариант использования. Вот два:
- Перенаправить stderr, очень похоже на redirect_stdout
- Временно измените sys.excepthook. Я много разрабатываю в интерактивном режиме, и когда я добавляю что-то в excludehook (заключая исходную функцию в одну из своих собственных, скажем, для регистрации исключений с помощью модуля ведения журнала), я обычно хочу, чтобы это было удалено в какой-то момент. Таким образом, у меня не будет все больше и больше копий моей функции, обертывающей саму себя. Этот вопрос сталкивается с тесно связанной проблемой.