2010-07-13 101 views
5

我有一个全局变量,我称为Y_VAL,它被初始化为2的值。为什么python认为这是一个局部变量?

然后我有一个函数,称为f()(为了简洁),它使用Y_VAL。

def f(): 
    y = Y_VAL 
    Y_VAL += 2 

但是,试图运行我的代码的时候,蟒蛇提供错误消息:

UnboundLocalError: local variable 'Y_VAL' referenced before assignment 

如果我删除最后一行Y_VAL += 2它工作正常。

为什么python认为Y_VAL是一个局部变量?

+0

可能的重复[为什么我不能在Python中设置全局变量?](http://stackoverflow.com/questions/1281184/why-cant-i-set-a-global-variable-in-python ) – Mark 2012-05-12 12:18:40

回答

14

您在函数内部缺少行global Y_VAL

Y_VAL在赋值的右侧出现时,由于先搜索本地作用域,然后搜索全局作用域,这没有问题。但是,在左侧,当您明确声明global Y_VAL时,只能将指定为

the docs

这将是不可能分配到一个全局变量没有全球性的,但自由变量可参考全局而不被声明为全局。

+0

这种行为是否适用于不同的字典?我发现我可以声明一个全局的字典,然后在不使用'global'的情况下在一个函数内赋值它......你可能知道这背后的推理吗? – VMDX 2010-07-13 22:14:10

+0

嗯,它看起来像我有与VMDX相同的问题。给定一个全局字典'd',我可以在不使用关键字global的情况下添加/更改它。这是怎么回事?与列表相同 – Paul 2010-07-13 22:15:56

+0

您可以更改列表或字典中的内容*。您不能更改(重新绑定)对列表/字典的引用。所以'd [2:] = 3'确定,但'd + = [3]'不是。 – bobince 2010-07-13 22:19:53

1

这就是Python的工作原理:作业始终绑定最近的名称空间中的左侧名称。函数内部最接近的名称空间是函数的本地名称空间。

为了分配给一个全局变量,你必须声明它为global。但是一定避免global。全局变量几乎总是不好的设计,因此使用关键字global是一个强烈的暗示,你正在犯设计错误。

0

在意识到需要全局声明之前,我遇到了与您一样的问题,以及其他像您一样的问题。然后我决定把所有的东西都移到面向对象的位置,并且有一丝心意。叫我疯了,但我只是不相信自己的全球声明,并不难以反对本地范围的问题,这是一个调试的痛苦。

所以我会建议收集所有的“全局”变量,把它们放在init(自我)里面的一个类中,而不仅仅是你不必担心局部范围,但你会让你的代码组织得更好。它不是运气的怪胎,大多数程序员都喜欢OOP。

相关问题