创建您自己的 Python 装饰器

1. 什么是装饰器

装饰器是Python中高级编程技巧之一,它能够在修改或者增强一个函数的功能时,不需要改变函数的代码。简而言之,它可以动态地修改一个类或者函数的功能。在Python中,函数是第一类对象,这意味着函数可以作为参数传递、并且可以返回其他函数。这个特性使得装饰器成为可能。

装饰器本质上是一个函数,它接收一个函数作为参数并且返回一个函数。

2. 函数装饰器

函数装饰器是使用装饰器语法对函数进行增强或修改的实现方式。被装饰的函数会作为装饰器定义的函数的参数,该装饰器函数可能会修改被装饰函数的行为,并且返回修改后的函数本身。

2.1 最简单的函数装饰器

最简单的函数装饰器包含两个函数。第一个函数接收一个函数作为参数,然后返回一个内部函数,这个内部函数实际上是原始函数的增强版本。以下是一个最简单的函数装饰器示例:

def my_decorator(func):

def wrapper():

print("Something is happening before the function is called.")

func()

print("Something is happening after the function is called.")

return wrapper

@my_decorator

def say_hello():

print("Hello!")

say_hello()

上面这个例子中,我们定义了一个装饰器函数my_decorator,它接收一个函数作为参数,返回一个内部函数wrapper。内部函数实现了对原始函数say_hello的修改增强,和原始函数名称一样的say_hello实际上指向了my_decorator返回的内部函数wrapper。这样,每次调用say_hello实际上会执行内部函数wrapper

运行结果如下,

Something is happening before the function is called.

Hello!

Something is happening after the function is called.

2.2 带参数的装饰器

my_decorator函数中,我们添加了*args**kwargs参数来允许接收任何参数,而这些参数可以传递给被装饰的函数。这样,我们可以通过在装饰器中定义*args**kwargs来对不同的函数进行装饰。

def my_decorator(func):

def wrapper(*args, **kwargs):

print("Something is happening before the function is called.")

func(*args, **kwargs)

print("Something is happening after the function is called.")

return wrapper

@my_decorator

def say_hello(name):

print(f"Hello {name}!")

say_hello("Python")

运行结果如下,

Something is happening before the function is called.

Hello Python!

Something is happening after the function is called.

3. 类装饰器

类装饰器是一种基于类的结构实现的装饰器,它可以对一个类或者类的方法进行增强或者修改。类装饰器接收一个类作为参数,然后在升级版本中返回一个新的类。这种方法可以视为对类的包装,旨在通过在对象上动态添加行为来增强类。

3.1 最简单的类装饰器

默认情况下,类装饰器会使用类的名称作为参数,并且包装的类的所有方法都可以被增强。以下是一个最简单的类装饰器示例:

class MyClassDecorator:

def __init__(self, cls):

self.cls = cls

def __call__(self, *args, **kwargs):

obj = self.cls(*args, **kwargs)

return obj

@MyClassDecorator

class MyClass:

def __init__(self, a, b):

self.a = a

self.b = b

def add(self):

return self.a+self.b

在上面的例子中,我们在类的上面应用了一个类装饰器MyClassDecorator,并且MyClassDecorator类包含了两个方法:构造函数和__call__。构造函数接收类作为参数,__call__方法用于实例化该类的对象并且返回。这样就为被包装的类提供了一个新的构造器。

运行结果如下,

obj = MyClass(1,2)

print(obj.add())

输出结果:

3

4. 多层装饰器

多层装饰器可以让我们在一个已经被包装的函数或类上持续添加新的增强功能。例如,我们可以创建一个几乎不会改变原有代码的单独装饰器,然后为我们的应用程序提供添加新的增强功能的方式。

我们可以使用多层装饰器来向代码添加多个功能,并且可以按照我们的需求自定义每个功能。

def decorator_1(func):

def wrapper(*args, **kwargs):

print("Decorator 1 started")

func(*args, **kwargs)

print("Decorator 1 ended")

return wrapper

def decorator_2(func):

def wrapper(*args, **kwargs):

print("Decorator 2 started")

func(*args, **kwargs)

print("Decorator 2 ended")

return wrapper

@decorator_1

@decorator_2

def say_hello():

print("Hello!")

say_hello()

运行结果如下,

Decorator 1 started

Decorator 2 started

Hello!

Decorator 2 ended

Decorator 1 ended

5. 总结

装饰器是Python编程中一项非常有用的技术。Python语言的函数式编程特性使得装饰器有了更灵活的应用。通过装饰器,我们可以动态地修改一个函数或类的功能而不需要修改原本的代码,这使得应用程序的可维护性更强。

后端开发标签