如何编写上下文管理器来将变量恢复为其原始值?例如:
x = 5
with Restorer(x):
x = 6
...
print(x)输出将是:5
发布于 2018-12-14 07:41:07
这只在特定情况下才有可能。通常,上下文管理器只获取x的值(实际上是一个引用)。它无法访问变量本身。
对于全局变量,如果调用函数是在同一模块中定义的(或者代码只是放在同一模块中,而没有包含函数),则可以将调用编写为
with Restorer('x'):那么恢复器可以类似于(省略错误检查):
class Restorer:
def __init__(self, varName):
self.varName = varName
def __enter__(self):
self.oldValue = globals()[self.varName]
def __exit__(self, exc_type, exc_val, exc_tb):
globals()[self.varName] = self.oldValue发布于 2018-12-14 07:49:07
利用contextlib.contextmanager,您可以在yield语句之后将x重新赋值为其原始值:
import contextlib
x = 5
@contextlib.contextmanager
def Restorer(val):
yield
global x
x = val
print(x)
with Restorer(x):
x = 6
print('in contextmanager:', x)
print('outside contextmanager', x)输出:
5
in contextmanager: 6
outside contextmanager 5发布于 2018-12-14 08:00:56
您可以滥用class语句来引入临时“作用域”:
x = 5
class Foo:
print(x)
x = 6
print(x)
print(x)这种“工作”是因为Foo没有建立一个真正的新作用域,这意味着第一个print(x)引用了当前作用域中的名称x,但是临时无人区中的赋值正在准备创建一个同名的类属性,并且该属性用于主体的其余部分。然而,我相信这足以模拟你所要求的。
(也就是说,在实践中不要实际使用它。如果您需要某种临时覆盖,请编写适当的函数或手动保存值。)
https://stackoverflow.com/questions/53771621
复制相似问题