Python中的闭包到底有什么用

2021年11月21日 阅读数:8
这篇文章主要向大家介绍Python中的闭包到底有什么用,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

一、global关键字的做用闭包

若是在函数中须要修改全局变量,则须要使用该关键字,具体参见下面例子。函数

variable=100
def function():
print(variable) #在函数内不对全局变量修改,直接访问是没问题的,不会报错
function() #输出100
 
variable=100
def function():
result=variable+111
print(result) #在函数内不对全局变量修改,直接使用是没问题的,不会报错
function() #输出211

 

variable=100
def function():
variable+=111
print(variable) #显示local variable 'variable' referenced before assignment。
#即在函数局部做用域中直接改变全局变量的值会报错
function()

 

variable=100
def function():
variable=1000 #此时修改variable变量的值不会报错,由于已经在函数局部做用域内从新定义variable,会覆盖全局variable。
variable+=111
print(variable)
function() #输出1111
print(variable) #输出100,虽然函数内部从新覆盖了variable,可是全局variable并未变,依然仍是100

 

 

那若是再也不函数内部从新为全局变量赋值,又想改变全局变量的值,应该怎么作呢?这就要使用global关键字了,以下。spa

 

variable=100
def function():
global variable #使用global关键字,代表variable是全局的,此时就能够了直接在函数局部做用域内改变variable的值了
variable+=111
print(variable) #输出211
function()
print(variable) #输出211,这和上面的不同了,发现全局变量variable自己也改变了

 

 

总结:global的做用就是在“函数局部做用域”内声明表示一个全局变量,从而能够在函数内部修改全局变量的值(不然只能访问不能修改),并且函数内部改变的全局变量的值也会改变。code

二、函数局部做用域对象

函数的局部做用域是不可以保存信息的,即在函数内部声明变量在函数调用结束以后函数里面保存的信息就被销毁了,包括函数的参数,以下。blog

 

def fun(step):
num=1
num+=step
print(num)

i=1
while(i<5):
fun(3) #连续调用函数4次,每次输出的值都是4,即3+1,这说明每次调用fun函数以后,函数内部定义局部变量num就被销毁了,
#没有保存下来,说明函数的局部做用域被销毁了。那若是要保存函数的局部变量,怎么办呢?引入“闭包”。
i+=1

 

 

三、闭包——装饰器的本质也是闭包作用域

“闭包”的本质就是函数的嵌套定义,即在函数内部再定义函数,以下所示。io

“闭包”有两种不一样的方式,第一种是在函数内部就“直接调用了”;第二种是“返回一个函数名称”。function

(1)第一种形式——直接调用class

 

def Maker(name):
num=100
def func1(weight,height,age):
weight+=1
height+=1
age+=1
print(name,weight,height,age)
func1(100,200,300) #在内部就直接调用“内部函数”
Maker('feifei') #调用外部函数,输出 feifei 101 201 301

 

 

(2)第二种形式——返回函数名称

 

def Maker(name):
num=100
def func1(weight,height,age):
weight+=1
height+=1
age+=1
print(name,weight,height,age)
return func1 #此处不直接调用,而是返回函数名称(Python中一切皆对象)
maker=Maker('feifei') #调用包装器
maker(100,200,300) #调用内部函数

 

 

(3)“闭包”的做用——保存函数的状态信息,使函数的局部变量信息依然能够保存下来,以下。

 

ef Maker(step): #包装器
num=1
def fun1(): #内部函数
nonlocal num #nonlocal关键字的做用和前面的local是同样的,若是不使用该关键字,则不能再内部函数改变“外部变量”的值
num=num+step #改变外部变量的值(若是只是访问外部变量,则不须要适用nonlocal)
print(num)
return fun1
#=====================================#
j=1
func2=Maker(3) #调用外部包装器
while(j<5):
func2() #调用内部函数4次 输出的结果是 四、七、十、13
j+=1

 

 

从上面的例子能够看出,外部装饰器函数的局部变量num=一、以及调用装饰器Maker(3)时候传入的参数step=3都被记忆了下来,因此才有1+3=四、4+3=七、7+3=十、10+3=13.

从这里能够看出,Maker函数虽然调用了,可是它的局部变量信息却被保存了下来,这就是“闭包”的最大的做用——保存局部信息不被销毁。

四、nonlocal关键字的做用

该关键字的做用和local的做用相似,就是让“内部函数”能够修改“外部函数(装饰器)”的局部变量值。详细信息这里不作讨论。