![](/img/trans.png)
[英]Python exec() NameError: name 'o' is not defined
[英]Python: weird “NameError: name … is not defined” in an 'exec' environment
我有信心至少對Python的范圍系統有一些基本的了解。 現在我收到一個錯誤,遺憾的是到目前為止我甚至無法為復制編寫好的代碼片段。 我嘗試在一個新的小項目中重現它,但一切都按照我的預期運行: - /
我只能描述我的所作所為,並希望有人能夠檢測出一種模式並告訴我這里可能出現的問題。
起初有一個python文件x.py
,它實現了一個類X
在其他一些python文件中,有以下字符串:
code="""
...
from x import X
...
class Y(X): # does not crash here, ...
def __init__(self):
X.__init__(self) # ... but here
...
foo=Y()
"""
你可以假設python能夠找到x
模塊。 在某個地方,我嘗試執行:
exec(code, globals(), locals())
現在我得到了NameError
。 它告訴我在嘗試調用它的構造函數時沒有定義X
它顯然定義在上面幾行。
如果我修改Y.__init__
並添加from x import X
作為第一行,它就可以了。 但為什么我要在那里再次導入呢?
如前所述,實際代碼更復雜,並且做了更多事情。 在一個不幸的情況下,我的帖子甚至沒有顯示實際導致問題的部分。 但也許你有一些一般的想法,如何才能得到這樣的行為。
這只是一個猜測,因為你沒有向我們展示足夠的代碼,你向我們展示的內容實際上並沒有重現問題,但......
如果你在函數中執行此exec
,那么locals()
和globals()
將會有所不同。 在這種情況下,代碼將像在類定義中一樣執行。 所以,它會(有點像)你這樣做:
class _:
from x import X
class Y(X): # does not crash here, ...
def __init__(self):
X.__init__(self) # ... but here
foo=Y()
del _
(我以前以為你也必須做類似Y()
外exec
,但user2357112的回答使我確信,是沒有必要的。)
如果那是你的問題,你可以通過調用exec(code, globals(), globals())
或exec(code, locals(), locals())
來修復它。 (哪一種適當,如果有的話,取決於你實際上想要做什么,當然,你沒有告訴我們。)
從exec
文檔 :
如果exec獲得兩個單獨的對象作為全局變量和局部變量,則代碼將被執行,就像它嵌入在類定義中一樣。
這有很好的理由,我不會在這里討論。
類定義中定義的函數不會查看變量分辨率的類定義的范圍。 exec
code
,它實際上是這樣執行的:
class Dummy:
from x import X
...
class Y(X):
def __init__(self):
X.__init__(self)
...
foo=Y()
這意味着這個功能:
def __init__(self):
X.__init__(self)
沒有看到這個變量:
from x import X
即使這一點:
class Y(X):
確實看到了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.