为什么访问全局变量不需要'global'关键字?

348 投票
11 回答
445220 浏览
提问于 2025-04-16 09:58

根据我的理解,Python 对函数有一个单独的命名空间,也就是说,如果我想在一个函数里使用全局变量,可能需要用到 global 这个关键词。

不过,我发现即使不使用 global,我也能访问到全局变量:

>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
...     return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'

那这是为什么呢?


另外,想了解更多可以查看 在第一次使用后重新赋值全局变量时出现的 UnboundLocalError 错误,还有 如何在函数中使用全局变量 的一般问题。

11 个回答

90

这段话讲的是在一个范围内访问变量名和将它绑定的区别。

如果你只是想查找一个变量的值,你可以访问全局范围和局部范围的变量。

但是,如果你给一个在局部范围内不存在的变量名赋值,你就是在这个范围内“绑定”了这个名字(如果这个名字在全局范围也存在,你就会把全局的那个隐藏起来)。

如果你想给全局的变量名赋值,你需要告诉解析器使用全局的名字,而不是绑定一个新的局部名字,这就是“global”这个关键词的作用。

在一个代码块内的任何地方进行绑定,会导致这个块内的所有地方都绑定这个名字,这可能会引发一些奇怪的后果(比如之前正常工作的代码突然出现UnboundLocalError错误)。

>>> a = 1
>>> def p():
    print(a) # accessing global scope, no binding going on
>>> def q():
    a = 3 # binding a name in local scope - hiding global
    print(a)
>>> def r():
    print(a) # fail - a is bound to local scope, but not assigned yet
    a = 4
>>> p()
1
>>> q()
3
>>> r()
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    r()
  File "<pyshell#32>", line 2, in r
    print(a) # fail - a is bound to local scope, but not assigned yet
UnboundLocalError: local variable 'a' referenced before assignment
>>> 
256

虽然你可以不使用 global 这个关键词就访问全局变量,但如果你想要修改这些全局变量,就必须使用 global 这个关键词。举个例子:

foo = 1
def test():
    foo = 2 # new local foo

def blub():
    global foo
    foo = 3 # changes the value of the global foo

在你的情况下,你只是访问了列表 sub

438

关键字 global 主要用来在一个局部环境中改变或创建全局变量,不过一般来说,创建全局变量并不是个好主意。

def bob():
    me = "locally defined"    # Defined only in local context
    print(me)

bob()
print(me)     # Asking for a global variable

上面的代码会给你:

locally defined
Traceback (most recent call last):
  File "file.py", line 9, in <module>
    print(me)
NameError: name 'me' is not defined

如果你使用 global 这个声明,变量就会在函数的外部也能使用,实际上变成了全局变量。

def bob():
    global me
    me = "locally defined"   # Defined locally but declared as global
    print(me)

bob()
print(me)     # Asking for a global variable

所以上面的代码会给你:

locally defined
locally defined

另外,由于 Python 的特性,你也可以在局部环境中用 global 来声明函数、类或其他对象。不过我建议不要这样做,因为如果出现问题或者需要调试,会让人很头疼。

撰写回答