您自己说,读取没有歧义,而写入则有歧义。因此,您需要一些机制来解决写入的歧义。
一种选择(可能实际上被更旧版本的 Python,IIRC 使用)只是说写入总是进入本地范围。那么就不需要global
关键字,也没有歧义。但是,您根本无法写入全局变量(不使用诸如globals()
以迂回方式获取它们的东西),所以这不会很好。
静态声明变量的语言使用的另一个选项是预先与每个范围的语言实现进行通信,哪些名称是本地的(您在该范围中声明的名称)以及哪些名称是全局的(在模块范围内声明的名称) . 但是 Python 没有声明变量,所以这个解决方案不起作用。
另一种选择是x = 3
仅在具有 name 的某个外部范围内没有名称时才分配给局部变量x
。似乎它会直观地做正确的事情?不过,这会导致一些严重讨厌的极端情况。目前,x = 3
将写入的位置由解析器静态确定;要么没有global x
在同一范围内,它是一个本地写入,要么有一个global x
,它是一个全局写入。但是,如果它将做什么取决于全局模块范围,则您必须等到运行时才能确定写入的位置,这意味着它可以在函数的调用之间发生变化. 考虑一下。每次在模块中创建全局变量时,都会更改模块中恰好使用该名称作为局部变量名称的所有函数的行为。做一些作为临时变量的模块范围计算,tmp
并告别在模块tmp
中的所有函数中使用。而且我不寒而栗地想到涉及在您导入的模块上分配属性然后从该模块调用函数的晦涩错误。呸。
另一种选择是与每个分配的语言实现进行通信,无论它应该是本地的还是全局的。这就是 Python 所做的。鉴于有一个涵盖几乎所有情况的合理默认值(写入局部变量),我们将局部赋值作为默认值,并用global
.
分配存在歧义,需要某种机制来解决它。global
就是这样一种机制。这不是唯一可能的,但在 Python 的上下文中,似乎所有替代机制都是可怕的。我不知道你在寻找什么样的“更好的理由”。