【发布时间】:2014-05-11 20:41:14
【问题描述】:
Python 3.4 提供了这个巧妙的工具来临时重定向标准输出:
# From https://docs.python.org/3.4/library/contextlib.html#contextlib.redirect_stdout
with redirect_stdout(sys.stderr):
help(pow)
The code 不是很复杂,但我不想一遍又一遍地写它,尤其是考虑到它已经考虑到让它可重入:
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。我以交互方式进行了很多开发,当我向异常钩子添加一些东西时(通过将原始函数包装在我自己的一个函数中,例如,使用日志记录模块记录异常),我通常希望它在某个时候被删除。这样我就不会有越来越多的包装自己的函数副本。 This question 面临一个密切相关的问题。
【问题讨论】:
-
你能激发这样的成语吗?在什么情况下会有用?
标签: python with-statement contextmanager