Python之装饰器

闭包

在了解装饰器之前,我们先了解一下闭包。所谓闭包,一般表现形式就是在一个函数里面,嵌套了子函数数,而子函数引用了函数的变量,所以到这这个变量在函数执行完的时候,并没有释放,而是继续存在,这就是闭包。

明确定义就是:闭包就是指有权访问另一个函数作用域中的变量的函数

先简单看两个例子:

1
2
3
4
5
6
7
8
9
10
11
12
# encoding:utf8
# python装饰器

def outer(arg):
def inner():
print(arg)
return inner

# 调用outer()方法其实返回了一个函数
inner = outer('hello world')
# 调用这个函数
inner()

输出结果:

1
hello world

在这个例子里面,我们实现了函数的嵌套,子函数调用父函数的局部变量(arg), 父函数返回子函数,所以我们调用父函数时,其实返回的是一个函数对象,我们可以继续执行这个函数,而且父函数的的局部变量并没有被垃圾回收,还是存在的。

我们试一下多层嵌套:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def outer(arg):
def inner():
def deeper():
print(arg)
return deeper
return inner


# 返回inner函数
inner = outer('hello world')
# 返回deeper函数
deeper = inner()
# 执行deeper函数
deeper()

输出结果:

1
hello world

通过两个例子,我们基本清楚了什么是闭包。

我们试一下把第一个代码示例中的参数改为一个函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# encoding:utf8
# python装饰器


def outer(func):
def inner():
func()
return inner


def func():
print('hello world')


inner=outer(func)
inner()

结果输出:

1
hello world

装饰器

对于这种编码写法,python提供了一种语法糖,也就是装饰器,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# encoding:utf8
# python装饰器


def outer(func):
def inner():
print('func will call')
func()
return inner

# python语法糖
@outer
def func():
print('hello world')


func()

输出结果和之前一样,写法和之前不同,只不过是在函数func上面加上了@outer函数名, 这个效果其实相当于:func=outer(func), func就变成了指向函数inner的指针,所以最后我们执行func()会调用inner()函数一样。

最后来个复杂的案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 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()
有用就打赏一下作者吧!