Python之装饰器
# 闭包
在了解装饰器之前,我们先了解一下闭包。所谓闭包,一般表现形式就是在一个函数里面,嵌套了子函数数,而子函数引用了函数的变量,所以到这这个变量在函数执行完的时候,并没有释放,而是继续存在,这就是闭包。
明确定义就是:闭包就是指有权访问另一个函数作用域中的变量的函数。
先简单看两个例子:
# encoding:utf8
# python装饰器
def outer(arg):
def inner():
print(arg)
return inner
# 调用outer()方法其实返回了一个函数
inner = outer('hello world')
# 调用这个函数
inner()
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
输出结果:
hello world
1
在这个例子里面,我们实现了函数的嵌套,子函数调用父函数的局部变量(arg), 父函数返回子函数,所以我们调用父函数时,其实返回的是一个函数对象,我们可以继续执行这个函数,而且父函数的的局部变量并没有被垃圾回收,还是存在的。
我们试一下多层嵌套:
def outer(arg):
def inner():
def deeper():
print(arg)
return deeper
return inner
# 返回inner函数
inner = outer('hello world')
# 返回deeper函数
deeper = inner()
# 执行deeper函数
deeper()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
输出结果:
hello world
1
通过两个例子,我们基本清楚了什么是闭包。
我们试一下把第一个代码示例中的参数改为一个函数:
# encoding:utf8
# python装饰器
def outer(func):
def inner():
func()
return inner
def func():
print('hello world')
inner=outer(func)
inner()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
结果输出:
hello world
1
# 装饰器
对于这种编码写法,python提供了一种语法糖,也就是装饰器,如下:
# encoding:utf8
# python装饰器
def outer(func):
def inner():
print('func will call')
func()
return inner
# python语法糖
@outer
def func():
print('hello world')
func()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
输出结果和之前一样,写法和之前不同,只不过是在函数func上面加上了@
和outer
函数名, 这个效果其实相当于:func=outer(func), func就变成了指向函数inner的指针,所以最后我们执行func()会调用inner()函数一样。
最后来个复杂的案例:
# encoding:utf8
# python装饰器
def outer(arg):
def inner(f):
def deeper():
f(arg)
return deeper
return inner
# 相当于 func = outer('hello world)(func),返回的是deeper函数
@outer('hello world')
def func(s):
print(s)
func()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
上次更新: 2022/12/01, 11:09:34