首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python上下文管理器恢复变量的值?

Python上下文管理器恢复变量的值?
EN

Stack Overflow用户
提问于 2018-12-14 07:38:21
回答 4查看 1K关注 0票数 4

如何编写上下文管理器来将变量恢复为其原始值?例如:

代码语言:javascript
复制
x = 5
with Restorer(x):
   x = 6
   ...
print(x)

输出将是:5

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-12-14 07:41:07

这只在特定情况下才有可能。通常,上下文管理器只获取x的值(实际上是一个引用)。它无法访问变量本身。

对于全局变量,如果调用函数是在同一模块中定义的(或者代码只是放在同一模块中,而没有包含函数),则可以将调用编写为

代码语言:javascript
复制
with Restorer('x'):

那么恢复器可以类似于(省略错误检查):

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2018-12-14 07:49:07

利用contextlib.contextmanager,您可以在yield语句之后将x重新赋值为其原始值:

代码语言:javascript
复制
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)

输出:

代码语言:javascript
复制
5
in contextmanager: 6
outside contextmanager 5
票数 0
EN

Stack Overflow用户

发布于 2018-12-14 08:00:56

您可以滥用class语句来引入临时“作用域”:

代码语言:javascript
复制
x = 5
class Foo:
    print(x)
    x = 6
    print(x)
print(x)

这种“工作”是因为Foo没有建立一个真正的新作用域,这意味着第一个print(x)引用了当前作用域中的名称x,但是临时无人区中的赋值正在准备创建一个同名的类属性,并且该属性用于主体的其余部分。然而,我相信这足以模拟你所要求的。

(也就是说,在实践中不要实际使用它。如果您需要某种临时覆盖,请编写适当的函数或手动保存值。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53771621

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档