Python的装饰器详解

本文最后更新于:2022年5月4日 晚上

介绍

Python的装饰器绝对算得上是一个十分有用的功能,可以极大的提高效率并减少代码量.

详细

介绍

要使用装饰器,首先需要了解python的函数。在python里,一切皆为函数。这里我们定义一个函数’start’

1
2
3
def start():
print('hi')
return "I am return"

此时我们有三种方式调用这个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 第一种
start()
# hi

# 第二种
func = start()
print(func)
# hi
# I am return

# 第三种
func = start
func()
# hi

区别在于

  1. 第一种通过直接调用函数,执行函数内的指令,但是没用输出函数的返回值
  2. 第二种执行函数,并把函数的返回值赋值给 func,再输出 func。 此时就得到了两条输出
  3. 直接把函数赋值给func(注意,赋值函数的时候并没用加上(), 加上的话就会直接执行), 再在func后面加上() 来执行函数,此时相当于直接执行 start()

装饰器是什么?

装饰器说白了就是可以在函数执行前,把函数给打包一遍,在函数前后可以加一些代码然后再执行。多用于后端的权限认证等功能

实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 首先创建一个装器饰
def co(func):
def wrapper():
print("hi")
func()
print("end")
return wrapper

# 在函数前加上'@装饰器名'
@co
def work():
print("I'm work")

# 执行函数
work()

# hi
# I'm work
# end

在执行 work() 的时候发生了什么?

  1. 首先,由于work的前面有装饰器的原因,在执行work的时候并不会直接先执行work。而是把 work这个对象(注意是’work’不是’work()’)传给 co 这个装饰器
  2. co 装饰器接收work对象,并且返回了wrapper这个对象。其中,wrapper对象执行了三条命令。 分别为 输出、执行函数、输出
  3. 于是python开始执行返回的这个wrapper,就输出了以上的结果

遇到有参数的情况怎么处理?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def co(func):
def wrapper(*args):
print("hi")
print("接收到了参数:", *args)
func(*args)
print("end")
return wrapper

@co
def work(request):
print("I'm work")


work("我是参数")

# hi
# 接收到了参数: 我是参数
# I'm work
# end

在遇到有参数的函数时,只需要在装饰器返回的函数(wrapper)里定义和传入函数(work)一样多的参数就可以. 当然,也可以用’*args’代替.
需要注意的是,在wrapper里的func()里,同样也需要把参数给传入进去,否则wrapper里的func将无法正常执行.

多个装饰器的情况下如何处理?

在多个装饰器的情况下,如

1
2
3
4
@newco
@co
def work():
print("I'm work")

work函数首先会传入到co的装饰器里,在co打包好并返回一个函数时(我们将返回的这个函数成为 newFunc), newFunc会作为函数传入到newco这个装饰器内,然后就和普通的装饰器一样的处理


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!