闭包的定义:如果在一个内部函数里,对在外部作用域(但不在全局作用域)的变量进行引用,那么这个内部函数就被称为闭包。
>>> def fun1(a):
def fun2(b): #fun2就是内部函数
return a * b #a就是被引用的外部作用域的变量,但是不在全局作用域里面
return fun2
>>> data = fun1(4)
>>>
>>> data(7)
28
闭包的概念由内部函数而来,所以不能在外部函数以外的地方对其调用。
外部函数的局部变量与内部函数局部变量的关系,就相当于全局变量和局部变量的关系,如果要在函数中修改全局变量,需要加上关键字 global,同样,如果要在内部函数里修改外部函数里的变量,需要加上关键字 nonlocal。
装饰器由闭包的概念引申而来,是一种增加函数或类功能的方法,它可以快速地给不同的函数或类传入相同的功能。
一个最简单的标准装饰器格式
def decorate(func_one): #定义一个函数
def wrapper(): #定义一个内部函数
func_one() #引用外部变量
return wrapper #返回内部函数
#写一个装饰器
>>> def decorate(func_one):
def wrapper():
print('do sth. before func_one')
func_one()
print('do sth. after func_one')
return wrapper
#将装饰器传入函数
>>> @decorate
def fun():
print("I'm the decorated function")
#调用函数
>>> fun()
do sth. before func_one
I'm the decorated function
do sth. after func_one
其实它的执行原理就是将函数作为参数传递给另一个函数,@符号只是一个快速生成被装饰函数的方式,如果不用@符号,还可以这样写
>>> def decorate(func_one):
def wrapper():
print('do sth. before func_one')
func_one()
print('do sth. after func_one')
return wrapper
>>> def fun():
print("I'm the decorated function")
>>> new_func = decorate(fun)
>>> new_func()
do sth. before func_one
I'm the decorated function
do sth. after func_one