如果想在一个函数中要为一个定义在函数外的「变量」赋值,也即是为全局变量赋值。我们使用global关键字。如果不适用global,就会报错。main方法是个例外
场景
在函数内部修改全局变量,报错
# -*- coding: utf-8 -*-
age = 18
def add_age():
age+=1
print "age {}, happy birthday ~".format(age)
add_age()
print "your age is {}".format(age)
报错信息
Traceback (most recent call last):
File "/PycharmProjects/Test/com/lyh/study/2019年03月17日01.py", line 8, in <module>
add_age()
File "/PycharmProjects/Test/com/lyh/study/2019年03月17日01.py", line 5, in add_age
age+=1
UnboundLocalError: local variable 'age' referenced before assignment
Process finished with exit code 1
Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的。
理论分析
- 函数定义了本地作用域,而模块定义的是全局作用域。
- 如果想要在函数内定义全局作用域,需要加上global修饰符。
LEGB原则
当在函数中使用未认证的变量名时,Python搜索4个作用域
- 本地作用域(L) 函数内部声明但没有使用global的变量 ;
- 本地作用域(E) def或者lambda;
- 全局作用域(G) 函数中使用global声明的变量或在模块层声明的变量;
- 内置作用域(B) 即python的内置类和函数等
在使用变量时,按照以上的顺序依次查找,并且在第一处能够找到这个变量名的地方停下来。如果变量名在整个的搜索过程中都没有找到,就会报错。
上边所说的变量规则只适用于简单对象,当出现引用对象时,则有另一套搜索规则:属性引用搜索一个或多个对象,而不是作用域,并且有可能涉及到所谓的"继承"
全局变量在函数中的使用
未使用global
函数只未定义重名变量
在模块层面定义的变量(无需global修饰),如果在函数中没有再定义同名变量,可以在函数中当做全局变量使用:
# -*- coding: utf-8 -*-
age = 18
def add_age():
age_1 = age+1
print "add age={}".format(age_1)
add_age()
print "your age is {}".format(age)
--------------------------------
#打印结果
add age=19
your age is 18
函数中的定义在引用前使用
而如果在函数中的定义在引用前使用,那么会正常运行但函数中的变量和模块中定义的全局变量不为同一个
age = 18
def add_age():
age = 19
print "add age={}".format(age)
add_age()
print "your age is {}".format(age)
--------------------------------
#打印结果
add age=19
your age is 18
但是如果使用如下的操作就会报错
age = 18
def add_age():
age += 1
print "add age={}".format(age)
add_age()
print "your age is {}".format(age)
--------------------------------
#打印结果
UnboundLocalError: local variable 'age' referenced before assignment
使用global
如果在函数使用某一变量后又对其进行修改(也即再赋值),怎么让函数里面使用全局变量而不是函数内部的局部变量呢?这时候global修饰符就派上用场了。
# -*- coding: utf-8 -*-
age = 18
def add_age():
global age
age += 1
print "add age={}".format(age)
add_age()
print "your age is {}".format(age)
------------------------------------
#输出结果
add age=19
your age is 19
注意 :global语句不允许同时进行赋值如global age =19 或者 global age+=1
总结
- 如果函数中变量无global关键字,优先读取局部变量,能读取全局变量,无法对全局变量赋值 age = 19(变量右边不能是“=”,对于可变变量可以进行追加删除等操作)
- 如果函数中变量有global关键字,可读取,可赋值 age = 19