簡體   English   中英

我正在嘗試了解Python的exec()函數

[英]I'm trying to understand Python's exec() function

所以我有一個像這樣的函數的字符串

code = """def somefn(x):
    return x + x
    y = somefn(z)"""

我試圖在另一個函數中運行它

def otherfn(codestr):
    z = 2
    exec(codestr)
    return y

otherfn(code)

但這給了我錯誤:

追溯(最近一次通話最近):文件“ C:/Users/Admin/Desktop/heh.py”,第11行,在其他fn(代碼)文件“ C:/Users/Admin/Desktop/heh.py”,第9行,在otherfn中返回y NameError:未定義名稱'y'

它在功能之外工作正常

z=2 exec(codestr) print(y)

它發現y很好,但不確定為什么在函數中時會出現bug。

我怎樣才能解決這個問題? 與globals()和locals()有關嗎? 使用Python 3.6 btw。

您的代碼有幾個問題。 首先,您有一個縮進問題yreturn后在somefn()函數內被“定義”,因此它實際上從未有機會進入堆棧。 您需要將code重新定義為:

code = """def somefn(x):
    return x + x
y = somefn(z)"""

但這只是冰山一角。 更大的問題是exec()無法修改函數的局部范圍。 這是由於以下事實:Python在本地范圍內不使用dict來查找變量,因此exec()所有更改都不會反映回堆棧以啟用查找。 這引起了一個奇怪的問題,其中exec()似乎改變了locals()字典,但是Python仍然拋出NameError

def otherfn(codestr):
    z = 2
    exec(codestr)
    print(locals()["y"])  # prints 4
    return y  # NameError

otherfn(code)

這是預期的行為,如issue4831中所述,並在官方文檔中進一步加以說明:

注意 :默認本地語言的行為與下面對函數locals()描述相同:不應嘗試對默認本地語言字典進行修改。 傳遞一個明確的當地人解釋,如果你需要看后當地人的功能代碼的作用exec()的回報。

但是,如果您必須反映更改,則可以執行后執行本地范圍更新:

def otherfn(codestr):
    z = 2
    locals_ = locals()
    exec(codestr, globals(), locals_)
    y = locals_["y"]
    return y

otherfn(code)

暫無
暫無

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

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