首先来看一下,简单的闭包函数:
def func(x):
def func1():
return x
return func1
>>g = func(3)
>>g()
>>3
1.内部函数可以对外部函数的变量进行操作
2.外部函数返回内部函数对象
满足以上两点,即是闭包
在上例中,外部函数变量x,被传入到内部函数func1中并返回,外部函数func返回内部函数的函数对象func1
函数对象加上()才为调用,否则只是函数对象,python万物皆对象
接下来,来看一下,内部函数带有参数的闭包
def func2(x):
def func3(y):
return x+y
return func3
>>g = func2(2)
>>g(3)
>>5
思考:当g = func2(2)执行完时,func2已经结束了,那么为什么x = 2实际上在g(2)还起作用呢?
因为当x = 2传入func2时,内部函数保留了这个实参
可以对代码做微小修改来表现:
def func2(x): #step1
#step2:
def func3(y): #step6
print(x)
return x+y#step7
return func3 #step3
>>g = func2(2) #step4
>>g(3) #step5
>>2
>>5
结合“函数对象可以作为函数参数”的特性,因此,这里的完全可以被赋值为一个函数对象,这是func2就成为了传入函数的装饰器
#一个输出函数__name__属性的装饰器
def printname(func):
def swarps(*args,**kwargs): #被修饰函数的参数将会成为内部函数的参数
print(func.__name__) #装饰器的意义在于此
return func(*args,**kwargs) #执行原被修饰的函数,不然原函数的结果不会返回
return swarps #返回函数对象
@printname
def square(x):
return x**2
square(2)
>>square
4
#将装饰器函数与闭包函数做比较
def printname(func): def func(x):
def swarps(*args,**kwargs): def func1(y):
print(func.__name__) <<#对外部参数操作>> print(x+2)
return func(*args,**kwargs) <<#对内外部函数一起做操作>> return x+y
return swarps <<#返回内部函数对象>> return func1
@printname
def square(x): g = func(3) >> g(2) == func(3)(2)
return x**2
#装饰器printname的执行过程
step1:将函数对象square传入printname的形参func
step2:在printname内部定义一个函数swarps并返回swarps,即printname(square) >>swarps
step3:x作为返回的函数对象swarps的参数,相当于执行swarps(x)
step4:执行swarp(x),并返回原函数的执行结果(return func(*args,*kwargs)一句,如果没有这一句,原函数的执行结果将被覆盖)
func(x)(y) >>printname(square)(x) 其实就是这样这样一种对应关系啦
函数名作为外部参数,函数参数作为内部参数的一个闭包而已,懂了吗?
下一个知识点:
带参数的装饰器,实际上就是对装饰器函数进行封装,举例来说,同样是刚才的printname装饰器
#一个简单的带参数装饰器
#对printname装饰器添加参数,要求当password = 5的时候才执行装饰器
def addargument(password):
def printname(func):
def swarps(*args,**kwargs):
if password == '5':
print(func.__name__)
return func(*args,**kwargs)
return swarps
return printname
@addargument(5)
def square(x):
return x**2
关于类装饰器,等学完了类和对象再来写吧