可参考自己廖雪峰python从零开始(五)
函数式编程之闭包
关于函数闭包的代码解释
闭包指延伸了作用域的函数,其中包含函数定义体中引用、但是不在定义体中定义的非全局变量。拿下图的装 饰器作为例子,内层函数averager的函数体中series就是一个列表的引用,但这个列表定义在了averager函数体外面,所以这就是个闭包,而变量series就是一个自由变量。自由变量指未在本地作用域中绑定的变量
#在Python中,只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,
# 其它的代码块(如if、try、for等)是不会引入新的作用域的
if 2>1:
x = 1
print(x) #结果为 1 因为if语句没有引入作用域
#def、class、lambda是可以引入新作用域的:
def test():
x = 2#因为x是局部作用域
print(x) #NameError: name 'x' is not defined
#global关键字声明的变量必须在全局作用域上,不能嵌套作用域上,
# 当要修改嵌套作用域(enclosing作用域,外层非全局作用域)中的变量就需要nonlocal关键字了:
def outer():
num = 25
def inner():
nonlocal num#nolocal声明保证了父级函数变量作用域子级函数作用域
print(num)#如果没有nolocal声明 此语句会因为函数内部没有对num定义而输出失败 输出25
num = 100
print(num) #输出100
#return inner() 也不能以return语句结束
inner()#注意此处函数的结束方式 如果不加此结束声明 函数为空
print(num) #输出100
outer()#注意函数内部不传入参数时函数是怎么结束的
#当内部作用域想修改外部作用域的变量时,
#当修改的变量是在全局作用域(global作用域)上的,就要使用global先声明一下
count = 20
print(count)
def outer():
global count#如果不加这句话会报错 UnboundLocalError: local variable 'count' referenced before assignment
#global声明 保证了全局变量的可以作用于函数的局部作用域
#count = count+1#如果不加全局声明 此语句会因为局部变量未定义而报错
print(count)#这里不加全局变量声明会报错,因为后续全局量的值已经被修改
#当全局变量的值在函数内部被修改时 函数内部必须加一个global声明
count = 200
print(count)#输出200
outer()#函数内部 加上全局变量声明之后 全局变量的值已经发生改变 输出200
print(count)#函数内部 加上全局变量声明之后 全局变量的值也会发生改变 输出200
#体会上述代码与底下代码来区别
count = 25
def outer():
#print(count)#在global声明之前就调用了该函数 后续又对函数值进行修改 函数作用域混乱
global count
count = count+5
print(count)
outer()
print(count)
#再有以下代码
count = 66
def outer():
print(count)
outer()
count = count+22
print(count)