Python之旅——带着决心出发(第0步)
一、基础篇
1.全局变量 VS 局部变量
a. 全局变量在整个文件内有效;
b.局部变量在函数内有效;
c.当全局变量和局部变量同名,局部变量有效。
若定义了全局变量,则可在函数内直接使用全局变量。
a = 1
b = [23, 98]
def func():
print("a = ", a) #使用全局变量
print("b = ", b)
b[0] = 9
print("b = ", b)
func()
输出结果:
a = 1
b = [23, 98]
b = [9, 98]
***Repl Closed***
若在函数内,存在对全局变量重新赋值,在Python中将可能解析为定义一个变量。
a = 1
b = [23, 98]
def func():
if(1 == a): #局部变量a定义前使用,语法错误
a = 2 #局部变量a定义
print("a = ", a)
print("b = ", b) #全局变量b
b[0] = 9
print("b = ", b)
func()
运行结果:
Traceback (most recent call last):
File "变量.py", line 13, in <module>
func()
File "变量.py", line 5, in func
if(1 == a):
UnboundLocalError: local variable 'a' referenced before assignment
***Repl Closed***
若需使用全局变量,则在函数内使用global关键字声明全局变量即可。
a = 1
b = [23, 98]
def func():
global a #全局变量
if(1 == a):
a = 2
print("a = ", a)
print("b = ", b)
b[0] = 9
print("b = ", b)
func()
输出结果:
a = 2
b = [23, 98]
b = [9, 98]
***Repl Closed***
若不需要使用全局变量,且和全局变量同名,则需要在函数内对其进行一次定义,再使用局部变量。
a = 1
b = [23, 98]
def func():
a = 1 #定义局部变量
if(1 == a):
a = 2
print("a = ", a)
print("b = ", b)
b[0] = 9
print("b = ", b)
func()
从前面的例子可以看出,对全局列表的某一个成员赋值符合语法规则。但是,函数内对与全局列表变量b再次赋值,即表示局部变量的定义。在变量定义之前使用,将会报告错误。
a = 1
b = [23, 98]
def func():
print("a = ", a)
print("b = ", b) #局部变量定义前使用,语法错误
b[0] = 9
print("b = ", b)
if(9 == b[0]):
b = [28, 98] #局部变量定义
print("b = ", b)
func()
输出结果:
a = 1
Traceback (most recent call last):
File "变量.py", line 15, in <module>
func()
File "变量.py", line 6, in func
print("b = ", b)
UnboundLocalError: local variable 'b' referenced before assignment
***Repl Closed***
综上所述:
1. 函数内对与全局变量同名的变量赋值,表示定义一个局部变量。变量必须先定义,后使用。
2. 对于列表类,可以对全局变量列表的一个元素b[0]重新赋值,不表示定义一个局部变量。
建议:
1. 避免定义一个和全局变量同名的局部变量;
2. 函数内使用全局变量,使用global在函数内对其进行声明。
2018年7月21日更新:
此处全局变量和局部变量的问题,其实就是最内嵌套作用域规则。
Python虚拟机在执行Python字节码时,会去搜索变量对象所在的作用域:
a.先从函数内local搜索变量对象;
b.再从全局(即文件内)global搜索变量对象;
c.最后从内建的(builtin)变量对象中搜索。
搜索不到对应的变量对象报告错误。