Python装饰器:类装饰器和函数式装饰器
在Python中,装饰器(Decorator)是一种特殊的语法,它可以用来修改或者扩展函数或类的功能。它是一种元编程(Metaprogramming)的方式,即编写可以编写其他代码的代码。
Python中的装饰器可以分为两种类型:类装饰器和函数式装饰器。本文将详细介绍这两种装饰器的概念和使用方法。
一、类装饰器
类装饰器是指可以通过类来实现的装饰器,即装饰器本身是一个类对象。它可以通过定义特殊方法__call__()来实现装饰器的功能,这个方法会在装饰器被调用时自动执行。
下面是一个使用类装饰器的例子:
class Logger:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print(f'Calling function {self.func.__name__}')
return self.func(*args, **kwargs)
@Logger
def add(a, b):
return a + b
print(add(1, 2))
上述代码定义了一个Logger类,该类接受一个函数作为参数,并在调用该函数时打印一条日志。然后,我们使用@符号将Logger类作为装饰器应用到add函数上。
执行上述代码,输出结果为:
Calling function add 3
可以看到,在调用add函数之前,Logger的__call__()方法先被调用,打印了一条日志。然后才调用了add函数,返回了正确的结果。
二、函数式装饰器
函数式装饰器是指通过函数来实现的装饰器,即装饰器本身就是一个函数。函数式装饰器的基本思路是,在装饰器函数内部定义一个新的函数,然后将原函数作为参数传递给新函数,并在新函数内部调用原函数。
下面是一个使用函数式装饰器的例子:
def logger(func):
def wrapper(*args, **kwargs):
print(f'Calling function {func.__name__}')
return func(*args, **kwargs)
return wrapper
@logger
def add(a, b):
return a + b
print(add(1, 2))
上述代码定义了一个logger函数,该函数接受一个函数作为参数,并在调用该函数时打印一条日志。然后,我们使用@符号将logger函数作为装饰器应用到add函数上。
执行上述代码,输出结果为:
Calling function add 3
可以看到,与类装饰器类似,调用add函数之前,装饰器函数logger先被调用,打印了一条日志。然后才调用了add函数,返回了正确的结果。
三、类装饰器与函数式装饰器的异同
类装饰器和函数式装饰器在实现装饰器功能上是等效的,它们的主要区别在于语法和使用方式。
1. 语法:类装饰器使用类对象来实现,使用__call__()方法来定义装饰器的逻辑;函数式装饰器使用函数来实现,将原函数作为参数传递给装饰器函数。
2. 使用方式:类装饰器通过在函数或者类上使用@符号来应用装饰器;函数式装饰器将原函数作为参数传递给装饰器函数,并将装饰器函数的返回值赋给原函数。
四、总结
类装饰器和函数式装饰器是Python中实现装饰器功能的两种方式,它们在语法和使用方式上有所不同,但在功能实现上是相同的。使用类装饰器或者函数式装饰器可以方便地扩展函数或类的功能,例如添加日志、权限检查等功能。在实际开发中,可以根据实际需求选择使用类装饰器或者函数式装饰器。
