你自己说过,读取时没有歧义,但写入时有。因此,你需要一些机制来解决写入的歧义。
一种选择(可能实际上被更早版本的Python使用)是仅将写入始终放在本地作用域中。然后就不需要使用
global
关键字,也没有歧义。但是这样你就无法写入全局变量了(除非使用像
globals()
这样的方法以迂回方式访问它们),所以这并不好。
另一种选项,由静态声明变量的语言使用,是为每个作用域与语言实现提前通信,哪些名称是本地的(在该作用域中声明的名称)以及哪些名称是全局的(在模块作用域中声明的名称)。但是Python没有声明变量,所以这种解决方案行不通。
另一种选项是,如果某个外部作用域中已经有一个名为
x
的名称,则
x = 3
只会分配给本地变量。这似乎直观地做到了正确的事情?但这会导致一些严重的棘手问题。目前,
x = 3
将写入的位置是由解析器静态确定的;如果同一作用域中没有
global x
,则它是一个本地写入,否则它是全局写入。但是如果它将要执行的操作取决于全局模块作用域,那么您必须等到运行时才能确定写入的位置
这意味着它会在函数调用之间改变。想象一下。每次在模块中创建一个全局变量,都会改变使用该名称作为本地变量名称的所有函数的行为。对于使用
tmp
作为临时变量的模块范围计算,并在该模块中分配属性然后调用该模块中的函数,我打个寒颤。
恶心。
另一种选项是,在每个赋值上向语言实现通信,以确定它应该是本地的还是全局的。这就是Python所采用的方法。鉴于几乎所有情况下都有一个合理的默认值(写入本地变量),我们将本地分配作为默认值,并使用
global
明确标记全局分配。
赋值存在歧义需要某种机制来解决。
global
是其中一种机制。虽然并非唯一可能的机制,但在Python的上下文中,似乎所有可替代的机制都很糟糕。我不知道你在寻找什么样的“更好的理由”。
global X
,那么语句X = 10
将创建一个绑定到10
的本地变量X
,而不是重新将全局变量X
绑定到10
。 - Dan D.