簡體   English   中英

scope 的全局變量,局部變量,與 exec() 一起使用

[英]scope of globals, locals, use with exec()

我很難理解 Python 中的globals()locals()的 scope。請考慮以下代碼:

def f1(glob, loc):
    exec("b = 5", glob, loc)


f1(globals(), locals())
print(b + 1)

這會將globalslocals變量傳遞給定義了變量b = 5f1 ,並且在主 scope 中的 function 調用之后確實存在。代碼正確打印

6

令我驚訝的是,當在 function 的 scope 中執行相同操作時, f2在這里失敗了:

def f1(glob, loc):
    exec("b = 5", glob, loc)


def f2():
    f1(globals(), locals())
    print(b + 1)


f2()
Traceback (most recent call last):
  File "/tmp/q.py", line 10, in <module>
    f2()
  File "/tmp/q.py", line 7, in f2
    print(b + 1)
NameError: name 'b' is not defined

這是為什么? 是否可以泛化f1以允許從f2調用它?

在您的第一個示例中, localsglobals字典,因為您處於模塊級別。

您可以使用print(id(globals()), id(locals()))檢查

在您的第二個示例中, locals是 function 的 scope 中的不同字典。

因此,要使示例 2 工作,請使用:

def f1(glob, loc):
    exec("b = 5", glob, loc)
def f2():
    f1(globals(), globals())
    print(b + 1)
f2()

或者

def f1(glob, loc):
    exec("b = 5", glob, glob)
def f2(loc):
    f1(globals(), loc)
    print(b + 1)
f2(locals())

所以這實際上不是exec()的問題,而是您在其中調用locals()的 scope 的問題。

而且這也是 exec 中的代碼做什么的問題,因為賦值會將名稱的 scope 更改為當前(本地)scope,除非涉及global / nonlocal 這就是為什么b=5在本地 scope 中執行的原因——除了在您的第一個示例中,“本地”scope 是全局scope。


跟進:

如果你想在f2中為b重新分配一個值,你將需要global關鍵字:

def f1(glob, loc):
    exec("b = 5", glob, loc)
def f2():
    f1(globals(), globals())
    global b
    b += 1
    print(b + 1) # 7
f2()

請注意,這與 exec 和傳遞 locals() / globals() 無關 - 您可以將其簡化為這個示例,如果沒有global關鍵字,它也會失敗(它會拋出UnboundLocalError: local variable 'b' referenced before assignment )。

b = 5
def f2():
    global b
    b += 1
    print(b + 1) # 7
f2()

這不是一個解釋性答案(傑森的評論似乎是一個很好的答案),但在工作中我編寫了一些使用exec的代碼,我發現exec(code, globals())是唯一有效的方法在任何情況下。 添加本地人作為參數只會導致各種問題。

調整您的代碼:

def f1(glob):
    exec("b = 5", glob)

def f2():
    f1(globals())
    print(b + 1)

f2()
# 6

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM