如果一个函数需要修改在全局范围内声明的变量,它需要用全局声明。 但是,如果函数只是需要读取一个全局变量,它可以这样做,而不使用全局声明:
X = 10
def foo():
global X
X = 20 # Needs global declaration
def bar():
print( X ) # Does not need global
我的问题是关于Python的设计:为什么Python的设计,让全局变量的读取,而不使用全局声明? 也就是说,为什么只有强制分配有全球性的,为什么不强加于读取过全球性的? (这将使它更优雅。)
注:我可以看到,有在阅读没有歧义,但如果打算创建一个新的局部变量或分配给全局的,而分配目前尚不清楚。 但是,我希望有这种不均匀的设计选择由BDFL更好的理由或意图。
看看下面的代码:
from module import function
def foo(x):
return function(x)
名称function
这里是一个全球性的。 如果我不得不说这会得到非常繁琐的global function
来获得此代码工作。
之前你说你的X
和我的function
是不同的(因为一个是一个变量,另一种是进口的功能),请记住,在Python的所有名称将被视为相同:使用时,其价值在作用域层级抬头。 如果您需要global X
,然后你需要global function
。 伊克。
随着嵌套范围,变量查找容易。 它们出现在链开始与当地人,通过封闭DEFS,到模块全局,然后建宏。 规则是第一场比赛中获胜。 因此,你不需要为查找一个“全球性”声明。
与此相反,写你需要指定写到哪个范围。 ,否则就没有办法确定“X = 10”的功能是否将意味着“写入到本地命名空间”或“写一个全局命名空间。”
内容提要,与写你有命名空间的选择,但是由于查找找到的第一个规则就足够了。 希望这可以帮助 :-)
编辑:是的,这就是这个样子“因为BDFL这么说的”,但它是不寻常在其他语言中没有类型声明有用于查找第一个发现的规则,只需要外地写的改性剂。 当你想想看,这两个规则导致非常干净的代码,因为范围修饰符只需要在最常见的情况(非本地写)。
由于显式优于隐式。
当你读一个变量有没有歧义。 你总是得到搜索范围最多时从局部到全球第一个找到的。
当您指定,这里只有两个作用域的解释可以明确地假设你分配给:本地和全局。 由于分配给当地是最常见的情况,并分配给全球不鼓励,这是默认的。 要分配给全球,你必须这样做明确的,告诉解释器,无论你使用的变量在此范围内,就应该直接进入全球范围内,你知道你在做什么。 在Python 3里,你也可以指定与“外地”最近的封闭范围。
请记住,当你分配给Python中的名字,这个新的任务无关与先前存在分配给别的东西的名称。 试想一下,如果没有默认为本地和Python搜查了试图找到该名称的变量,因为读取的时候不分配给它的所有范围。 你的函数的行为可能会改变不仅仅基于你的参数,但在封闭范围。 生活会很惨。
你自己说,这与读取没有歧义,并写有。 因此,你需要一些机制来解决与写入的不确定性。
一个选项(可能实际使用的更老版本的Python,IIRC)的是刚刚说的写操作经常去当地的范围。 那么有没有必要为一个global
的关键字,而不会产生歧义。 但你不能写入到全局变量在所有(没有使用像globals()
他们在一个迂回的方式获得),这样就不会很大。
另一种选择,通过语言使用的静态声明变量,是沟通的语言实现的前期每一个范围,其名称是本地(即您可以在该范围内声明)和其名称是全局(在模块范围内声明的名字) 。 但是Python没有声明的变量,因此该方案是行不通的。
另一种选择是有x = 3
赋值给一个局部变量只如果没有已经与一些名外部范围的名称x
。 好像它会直觉地做正确的事? 这会导致一些严重的高难度弯道的情况下,虽然。 目前,其中x = 3
将写入静态由解析器确定; 无论有没有global x
在相同的范围内,这是一个本地写,或者是有global x
,这是一个全球性的写入。 但是,如果它会做取决于全球模块范围内,你必须等待,直到运行时确定在写去,这意味着它可以在函数的调用之间改变 。 考虑一下。 你一个模块中创建一个全球性的每一次,你会改变的是发生在使用该名称作为一个局部变量名的模块中的所有功能的行为。 不要使用一些模块范围计算tmp
作为一个临时变量,告别使用tmp
在模块中的所有功能。 我不敢想像涉及分配已经导入一个模块上的属性,然后调用该模块的功能晦涩的错误。 呸 。
而另一种选择是沟通对每项任务是否应该本地或全局的语言实现。 这是Python的已经有。 假设有一个合理的默认覆盖几乎所有情况下(写入局部变量),我们有局部分配为默认,并明确标示出全球分配global
。
没有与任务,需要一些机制来解决这个问题的不确定性。 global
是一个这样的机制。 这不是唯一可能的,但在Python的情况下,似乎所有的替代机制是太可怕了。 我不知道是什么样的“更好的理由”,你要寻找的。