簡體   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