注意:有一个非常相似的问题here。但是,忍受我吧;我的问题不是“为什么会发生错误”,而是“为什么要实现Python以在这种情况下引发错误”。

我偶然发现了这一点:

a = 5
def x()
    print a
    a = 6
x()

抛出UnboundLocalException。现在,我知道为什么会发生这种情况(在此作用域之后,绑定(bind)了a,因此整个范围将a视为本地的)。

在这种情况下:
a = 5
def x()
    print b
    b = 6
x()

这很有道理。但是第一种情况具有直观的逻辑,这意味着:
a = 5
def x()
    print globals()["a"]
    a = 6 # local assignment
x()

我猜有一个为什么不允许“直观”版本的原因,但这是什么呢?尽管这可能是“显式比隐式更好”的情况,但是摆弄globals()总是让我感到有些不整洁。

从一个角度来看,发生在我身上的实际情况是我不得不改变一下别人的脚本。在我的(短暂的)更改中,我在脚本运行时做了一些文件重命名,所以我插入了
import os
os.rename("foo", "bar")

进入脚本。这种插入发生在函数内部。该模块已经在顶层导入了os(我没有检查过),并且在函数内部但在我插入之前进行了一些os.somefunction调用。这些调用显然触发了UnboundLocalException

那么,有人可以向我解释此实现背后的原因吗?是否可以防止用户犯错误?对于字节码编译器,“直观”的方式只会使事情变得更复杂吗?还是我可能没有想到的歧义?

最佳答案

具有相同名称的相同名称是指在同一线性代码流中完全不同的变量,这令人难以置信的复杂性使它错开了头脑。考虑:

def aaaargh(alist):
  for x in alist:
    print a
    a = 23

在所需的Python变体中,此代码应该做什么?在相同的a语句中,print是否在循环的第一回合与第二个回合(假设还有第二个)中引用完全不同且不相关的变量?即使对于单项列表,它的工作方式是否也与非循环代码不同?认真地说,这种疯狂的方式在于说谎-甚至没有想到可怕的实现问题,只是尝试记录和教导这一点,这可能会使我切换语言。

语言,其实现者,其老师,其学习者,其从业者承担所有这些概念负担的基本动机是什么,以支持和鼓励半隐式,非明示使用GLOBAL VARIABLES?这似乎不是一个值得的目标,是吗?

10-06 08:20