繁体   English   中英

Python Context Manager恢复变量的值?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM