当我们需要在现有的函数或类中添加一些额外的功能时,我们不希望直接修改原来的函数或类,而是需要一种方式能够在不改变原有代码的基础上扩展它的功能。因此,Python中提供了装饰器(Decorator)这种编程方式。
装饰器本质上就是一个函数,可以在运行时动态地增加功能到某个函数或类上。Python中使用 @ 符号,将一个函数或类传递给装饰器函数,进而执行装饰器的功能。
下面是Python装饰器的使用方法攻略及示例:
装饰器的基本使用
- 创建一个简单的装饰器
def my_decorator(func):
def wrapper():
print("执行函数之前的操作")
func()
print("执行函数之后的操作")
return wrapper
@my_decorator
def say_hello():
print("你好")
say_hello()
在上面的代码中,我们定义了一个装饰器 my_decorator。它接收一个参数 func,用来表示需要装饰的函数。wrapper 函数是内部的函数,负责添加额外的功能。最后返回 wrapper 函数。
在下面的代码中,使用 @my_decorator 装饰函数 say_hello。当我们调用 say_hello 的时候,实际上是在执行 my_decorator 函数中的 wrapper 函数,因此可以看到输出 “执行函数之前的操作”、”你好” 和 “执行函数之后的操作”。
- 装饰器中使用参数
def my_decorator(func):
def wrapper(*args, **kwargs):
print("执行函数之前的操作")
func(*args, **kwargs)
print("执行函数之后的操作")
return wrapper
@my_decorator
def say_hello(name):
print("你好,{}".format(name))
say_hello("小明")
在上面的代码中,我们定义了一个装饰器 my_decorator,并将参数 args 和 kwargs 传递给了 wrapper 函数。当使用装饰器装饰函数 say_hello 时,我们需要传递调用 say_hello 所需的参数。当我们调用 say_hello 函数时,装饰器会自动解析传入的参数,并将参数传递给原始函数。
装饰器的高级使用
- 为装饰器增加参数
def repeat(num):
def my_decorator(func):
def wrapper(*args, **kwargs):
for i in range(num):
print("执行函数之前的操作")
func(*args, **kwargs)
print("执行函数之后的操作")
return wrapper
return my_decorator
@repeat(num=3)
def say_hello(name):
print("你好,{}".format(name))
say_hello("小明")
在上面的代码中,我们在装饰器函数 my_decorator 外包了一层函数 repeat,将其作为一个参数传递给 my_decorator。我们可以使用 @repeat(num=3) 的方式来将装饰器装饰到函数上,并传递repeat函数所需的参数 num。当我们调用 say_hello 时,将会执行三次函数。
- 对类进行装饰
def my_decorator(cls):
class NewCls:
def __init__(self, *args, **kwargs):
self.obj = cls(*args, **kwargs)
def __getattr__(self, name):
print("在执行函数之前的操作")
return getattr(self.obj, name)
return NewCls
@my_decorator
class MyClass:
def __init__(self, x, y):
self.x = x
self.y = y
def add(self):
return self.x + self.y
obj = MyClass(4, 5)
print(obj.add())
在上面的代码中,我们定义了一个装饰器 my_decorator。我们使用它来修饰类 MyClass,并定义了一个新的类 NewCls。在 NewCls 中,我们重写了 init 和 getattr 方法,将被装饰的类 MyClass 实例化,并将其作为其实例属性 self.obj。当我们调用 MyClass 的方法时,在执行函数之前,会打印 “在执行函数之前的操作”,并返回被装饰类的方法。通过对类的装饰,可以扩展类的功能,使其更加灵活和功能强大。