变量的作用域
“在python中,当引用一个变量的时候,对这个变量的搜索是按照本地作用域(local)、嵌套作用域(enclosing function locals)、全局作用域(global)、内置作用域(builtins模块)的顺序来进行的,即所谓的legb规则。”
“当在函数中给一个变量名赋值是(而不是在一个表达式中对其进行引用),Python总是创建或改变本地作用域的变量名,除非它已经在那个函数中被声明为全局变量。”
-
定义的函数内部变量名如果是第一次出现,且在=符号之前,name就可以认为是被定义为局部变量。在这种情况下,不论全局变量中是否用到该变量名,函数中使用的都是局部变量。例如:
num = 100 def fuc(): num =123 print(num) func() # 输出结果123
-
函数内部的变量名如果是第一次出现,且出现在=符号后面,且在之前已被定义为全局变量,则这里将引用全局变量。例如:
num = 100 def func(): x = num + 100 print x func() # 输出结果200
-
函数中使用某个变量,如果该变量名既有全局变量也有局部变量,则默认使用局部变量。例如:
num = 100 def func(): num = 200 x = num + 100 print(x) func() # 输出结果300
在函数中将某个变量定义为全局变量时需要使用关键字global。
python变量的作用域
变量作用域(scope)在python中是一个容易掉坑的地方。
python的作用域一共有四种,分别是:
L(Local) 局部作用域
E(Enclosing) 闭包函数外的函数中
G(Global) 全局作用域
B(Built-in) 内建作用域
以L->E->G->B的规则查找,即:局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。
Python除了def/class/lambda外,其他如:if/elif/else/ try/except for/while并不能改变其作用域。定义在他们之内的变量,外部还是可以访问。
if True:
a='i am A'
a
定义在if语言中的变量a,外部还是可以访问的。
但是需要注意如果if被def/class/lambda包裹,在内部赋值,就变成了此函数/类/lambda的局部作用域。
在def/class/lambda内进行赋值,就变成了其局部的作用域,局部作用域会覆盖全局作用域,但不会影响全局作用域。
g = 1
def fun():
g = 2 #局部的
return g
print fun()
# 结果为2
print g
# 结果为1
但是要注意,有时候在函数内部引用全局的变量,疏忽了就会出现错误,比如:
#file1.py
var = 1
def fun():
print var
var = 200
print fun()
#file2.py
var = 1
def fun():
var = var + 1
return var
print fun()
这两个函数都会报错UnboundLocalError: local variable 'var' referenced before assignment在未被赋值之前引用的错误!为什么?因为在函数的内部,解释器探测到var被重新赋值了,所以var成为了局部变量,但是在没有被赋值之前就想使用var,便会出现这个错误。解决的方法是在函数内部添加 globals var 但运行函数后全局的var也会被修改。