闭包
函数内的属性,都是在函数执行期间存活
内部函数对外部函数作用域里变量的引用,闭包内的闭包函数把变量私有化了,完成数据的封装
#a1为外部函数
def a1(a):
b = 1
#a2为内部函数
def a2():
print(a+b)
return a2
if __name__ == '__main__':
test = a1(2)
test()
这个就是典型的闭包格式,内部函数要调用外部的参数然后把调用外部参数的函数返回形成闭包,调用a1时就相当于调用a2。
装饰器
在运行函数时,对函数的功能进行拓展,并且不影响函数的功能,闭包就通畅运用在装饰器中。
def a1(obj):
def a2():
print('你好')
return obj()
return a2
@a1
def b():
print('我是b')
b()
这就是一个典型的装饰器,使用语法糖@来进行调用,最后输出的结果为‘你好我是b’,obj为形参,没有设置的话使用装饰器会报错,@a1相当于a1(b)(),即把函数b传进去,然后执行a2打印’你好’,然后return b()打印’我是b’。即a1(b)()–>a2()–>b(),因为上面闭包返回的是a2,所以a1()()就相当于是a2()。
装饰器带参数
def a1(n):
def a2(obj):
def a3():
if n == '1':
print('这是1')
if n == '2':
print('这是2')
return obj()
return a3
return a2
@a1(n='1')
def num_1():
print('我是1')
@a1(n='2')
def num_2():
print('我是2')
num_1()
num_2()
如果装饰器需要带参数,可以闭包当中多一层,这样可以把参数传给最外层,然后第二层函数接收被装饰函数,接下来就跟普通的装饰器一样了。
被装饰函数当参数
def a1(obj):
def a2(c,d):
print(c,d)
c += 1
d += 1
return obj(c,d)
return a2
@a1
def b(x,y):
print(x + y)
b(1,1)
外层函数接收被装饰函数,内部函数接收被装饰函数的参数。