[英]Python Context Manager to restore a variable's value?
您将如何编写上下文管理器以将变量恢复为其原始值? 例如:
x = 5
with Restorer(x):
x = 6
...
print(x)
输出将是:5
仅在特定情况下才有可能。 通常,上下文管理器仅获取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
利用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
您可以滥用class
声明来引入临时“作用域”:
x = 5
class Foo:
print(x)
x = 6
print(x)
print(x)
之所以可行,是因为Foo
并没有建立真正的新作用域,这意味着第一个print(x)
引用了当前作用域内的名称x
,而是在一个临时的无人区域进行赋值,以通过以下方式创建类属性名称相同,并且该属性用于正文的其余部分。 但是,我相信这足以模拟您的要求。
(也就是说,实际上不要实际使用它。如果需要某种临时替代,请编写适当的函数或手动保存值。)
这更多是与名称范围有关,而不是变量。
您可以通过创建具有该块行为的函数来创建作用域:
def behaviour():
x = 6
...
x = 5
behaviour()
print(x)
输出:
5
另外,您可以引入一个新名称:
x = 5
y = 6
...
print(x)
输出:
5
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.