在Python中使用“global”关键字

Use of “global” keyword in Python

我从阅读文档中了解到,python有一个单独的函数名称空间,如果我想在该函数中使用一个全局变量,我需要使用global

我使用的是python 2.7,我尝试了这个小测试

1
2
3
4
5
6
>>> sub = ['0', '0', '0', '0']
>>> def getJoin():
...     return '.'.join(sub)
...
>>> getJoin()
'0.0.0.0'

即使没有global,情况似乎也很好。我能够访问全局变量而没有任何问题。

我错过什么了吗?另外,下面是来自python文档的:

Names listed in a global statement
must not be defined as formal
parameters or in a for loop control
target, class definition, function
definition, or import statement.

虽然形式参数和类定义对我来说很有意义,但是我不能理解对循环控制目标和函数定义的限制。


关键字global只对在本地上下文中更改或创建全局变量有用,尽管创建全局变量很少被认为是一个好的解决方案。

1
2
3
4
5
6
def bob():
    me ="locally defined"    # Defined only in local context
    print me

bob()
print me     # Asking for a global variable

以上内容将为您提供:

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

当您使用global语句时,变量将"超出"函数的范围,有效地成为全局变量。

1
2
3
4
5
6
7
def bob():
    global me
    me ="locally defined"   # Defined locally but declared as global
    print me

bob()
print me     # Asking for a global variable

所以上面的代码会给你:

1
2
locally defined
locally defined

此外,由于python的特性,还可以使用global在本地上下文中声明函数、类或其他对象。尽管我建议不要这样做,因为如果有什么地方出错或需要调试,它会导致噩梦。


虽然您可以在不使用global关键字的情况下访问全局变量,但如果要修改这些变量,则必须使用global关键字。例如:

1
2
3
4
5
6
7
foo = 1
def test():
    foo = 2 # new local foo

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

在您的情况下,您只需访问列表sub


这是访问名称和在作用域内绑定名称之间的区别。

如果您只是查找一个变量来读取它的值,那么您可以访问全局和本地范围。

但是,如果为一个名称不在本地作用域中的变量赋值,则将该名称绑定到此作用域中(如果该名称也作为全局名称存在,则将其隐藏)。

如果您希望能够分配给全局名称,您需要告诉解析器使用全局名称,而不是绑定一个新的本地名称,这就是"global"关键字所做的。

在一个块中的任何地方绑定都会导致该块中的所有地方的名称都被绑定,这可能会导致一些看起来很奇怪的结果(例如,unboundLocalError突然出现在以前工作的代码中)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
>>> 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
>>>


其他答案回答你的问题。关于python中的名称,另一件重要的事情是它们在每个作用域的基础上要么是本地的,要么是全局的。

考虑一下,例如:

1
2
3
4
5
6
7
8
value = 42

def doit():
    print value
    value = 0

doit()
print value

您可能会猜测,value = 0语句将分配给局部变量,而不会影响在doit()函数之外声明的相同变量的值。您可能会更惊讶地发现上面的代码不会运行。函数内部的语句print value生成一个UnboundLocalError.

原因是python注意到,在函数的其他地方,您指定了名称value,并且value也没有声明为global。这使得它成为一个局部变量。但是当您尝试打印时,本地名称还没有定义。在本例中,python不会像其他一些语言那样将名称作为全局变量来查找。本质上,如果在函数的任何位置定义了同名的局部变量,则无法访问全局变量。


访问名称和分配名称是不同的。在您的情况下,您只是访问一个名称。

如果为函数中的变量赋值,则除非将该变量声明为全局变量,否则假定该变量为局部变量。如果没有,则假定它是全局的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> x = 1         # global
>>> def foo():
        print x       # accessing it, it is global

>>> foo()
1
>>> def foo():  
        x = 2        # local x
        print x

>>> x            # global x
1
>>> foo()        # prints local x
2

  • 您可以访问不带关键字global的全局关键字。
  • 为了能够修改它们,您需要显式地声明关键字是全局的。否则,关键字将在本地范围内声明。

例子:

1
2
3
4
5
6
7
8
9
10
words = [...]

def contains (word):
    global words             # <- not really needed
    return (word in words)

def add (word):
    global words             # must specify that we're working with a global keyword
    if word not in words:
        words += [word]


在函数外部声明的任何变量都被假定为全局变量,只有在从函数内部(构造函数除外)声明它们时,才必须指定该变量为全局变量。


我给你举个简单的例子:想想这个代码:

1
2
3
4
5
6
7
8
9
myVar = 0
print (myVar )      # 01 line: returns 0

def func():
    myVar  ="def"
    print (myVar )

func()              # 02 line: returns def
print (myVar )      # 03 line: returns 0

正如您所看到的,最后一行代码将返回0,因为在函数内部,myvar变量没有被重新分配,它只是被修改过,只有在调用函数时它才会更改,而不会影响主myvar变量,因为它是在我们的函数内部定义的(意味着它是局部变量),但使用global关键字作为这样的:

1
2
3
4
5
6
7
8
9
10
 myVar  = 0
print (myVar )       # 01 Line : returns 0

def func():
    global myVar
    myVar  ="def"
    print (myVar )

func()               # 02 Line : returns def
print (myVar )       # 03 Line : returns def

我们实际上对python进行了排序,认为def中的这个变量不是本地变量,使用名为myvar的全局变量来更改它。


全局使变量"全局"

1
2
3
4
5
6
7
8
9
10
def out():
    global x
    x = 1
    print(x)
    return


out()

print (x)

这使得"x"在函数外部的作用类似于一个普通变量。如果您取出全局变量,那么它将给出一个错误,因为它无法在函数内打印变量。

1
2
3
4
5
6
7
8
9
10
def out():
     # Taking out the global will give you an error since the variable x is no longer 'global' or in other words: accessible for other commands
    x = 1
    print(x)
    return


out()

print (x)

这意味着您不应执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
x = 1

def myfunc():
  global x

  # formal parameter
  def localfunction(x):
    return x+1

  # import statement
  import os.path as x

  # for loop control target
  for x in range(10):
    print x

  # class definition
  class x(object):
    def __init__(self):
      pass

  #function definition
  def x():
    print"I'm bad"