簡體   English   中英

Python:在'exec'環境中奇怪的“NameError:name ...未定義”

[英]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.

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