5.8 【基础】变量的作用域¶
1. 作用域¶
Python的作用域可以分为四种:
L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域
变量/函数 的查找顺序: L –> E –> G –>B
意思是,在局部找不到的,便去局部外的局部作用域找(例如 闭包),再找不到的就去全局作业域里找,再找不到就去内建作业域中找。
会影响 变量/函数 作用范围的有
函数:def 或 lambda
类:class
关键字:global noglobal
文件:*py
推导式:[],{},()等,仅限Py3.x中,Py2.x会出现变量泄露。
1、赋值在前,引用在后
# ------同作用域内------
name = "MING"
print(name)
# ------不同作用域内------
name = "MING"
def main():
print(name)
2、引用在前,赋值在后(同一作用域内)
print(name)
name = "MING"
# UnboundLocalError: local variable 'name' referenced before assignment
3、赋值在低层,引用在高层
# L -> E -> G -> B
# 从左到右,由低层到高层
def main():
name = "MING"
print(name)
# NameError: name 'name' is not defined
2. 闭包¶
闭包这个概念很重要噢。你一定要掌握。
在一个外函数中定义了一个内函数,内函数里运用了外函数的临时变量,并且外函数的返回值是内函数的引用。这样就构成了一个闭包。其实装饰函数,很多都是闭包。
好像并不难理解,为什么初学者会觉得闭包难以理解呢?
我解释一下,你就明白了。
一般情况下,在我们认知当中,如果一个函数结束,函数的内部所有东西都会释放掉,还给内存,局部变量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的临时变量将来会在内部函数中用到,就把这个临时变量绑定给了内部函数,然后自己再结束。
你可以看下面这段代码,就构成了闭包。在内函数里可以引用外函数的变量。
def deco():
name = "MING"
def wrapper():
print(name)
return wrapper
deco()()
# 输出:MING