详解 Python 函数装饰器的3种用法

1. 概述

在 Python 中,函数是第一类对象,可以作为参数传递,也可以作为返回值返回。这种特性使得 Python 函数在编程中扮演着非常重要的角色。函数装饰器是 Python 中的一种高级编程技巧,使用装饰器可以在不改变原函数代码的情况下,增强函数的功能。Python 中常用的装饰器有函数装饰器和类装饰器两种。本文将详解 Python 函数装饰器的3种用法。

2. 函数装饰器的基本用法

2.1. 函数装饰器的定义

函数装饰器是一个函数,它可以接收一个函数作为参数,对这个函数进行修改或者增强,最后返回被修饰后的新函数。

以下是一个简单的函数装饰器示例:

def my_decorator(func):

def wrapper():

print("在调用函数之前,我可以做一些事情")

func()

print("在调用函数之后,我可以做一些事情")

return wrapper

@my_decorator

def say_hello():

print("hello")

say_hello()

运行以上代码,输出:

在调用函数之前,我可以做一些事情

hello

在调用函数之后,我可以做一些事情

以上代码定义了一个名为 my_decorator 的函数装饰器,它接收一个函数作为参数。然后定义了一个名为 wrapper 的嵌套函数,wrapper 函数中先打印一行文字,再调用参数函数 func,最后再打印一行文字。最后再返回 wrapper 函数。

say_hello 函数定义上方加上 @my_decorator,相当于将 say_hello 函数传递给 my_decorator 函数,把 say_hello 函数的引用覆盖了,同时重新指向了返回的 wrapper 函数。

2.2. 带有参数的函数装饰器

和普通函数一样,函数装饰器也可以带有参数,只需要在定义函数的外层包裹一层函数,用于接收装饰器参数。以下是一个带有参数的函数装饰器示例:

def logger(level):

def decorator(func):

def wrapper(*args, **kwargs):

print("[{level}] 函数 {func.__name__} 被调用了".format(level=level, func=func))

return func(*args, **kwargs)

return wrapper

return decorator

@logger(level="INFO")

def say_hello(name):

print("hello {name}".format(name=name))

say_hello("world")

运行以上代码,输出:

[INFO] 函数 say_hello 被调用了

hello world

以上代码定义了一个名为 logger 的函数,它接收一个参数 level,返回一个无参数的装饰器函数 decorator。 在 decorator 函数内部又定义了一个名为 wrapper 的嵌套函数,该函数接收任意数量和类型的位置参数和关键字参数,并在输出函数被调用的日志信息后,调用被装饰函数。最后再返回 wrapper 函数。

say_hello 函数定义上方加上 @logger(level="INFO"),表示将 say_hello 函数传递给 logger 函数,并传递参数 level="INFO",从而返回一个新的增强过的函数 wrapper

3. 多个装饰器的装饰

3.1. 装饰器顺序

当多个装饰器同时装饰一个函数时,它们的执行顺序从上到下,即最上面的装饰器会最先执行。

以下是一个多个装饰器的示例:

def make_bold(func):

def wrapper():

return "" + func() + ""

return wrapper

def make_italic(func):

def wrapper():

return "" + func() + ""

return wrapper

@make_bold

@make_italic

def say_hello():

return "hello"

print(say_hello())

运行以上代码,输出:

hello

say_hello 函数定义上方加上 @make_bold@make_italic,表示将 say_hello 函数先传递给 make_italic 函数,再将返回值(即新的函数)传递给 make_bold 函数,最终得到增强后的新函数。

3.2. 带有参数的装饰器的装饰

当装饰器带有参数时,需要再增加一层函数来接收权重值,并返回装饰器。

以下是一个带有参数的多重装饰器示例:

def repeat(times):

def decorator(func):

def wrapper():

for i in range(times):

func()

return wrapper

return decorator

def make_bold(func):

def wrapper():

return "" + func()() + ""

return wrapper

def make_italic(func):

def wrapper():

return "" + func()() + ""

return wrapper

@make_bold

@make_italic

@repeat(3)

def say_hello():

return "hello"

print(say_hello())

运行以上代码,输出:

hellohellohello

say_hello 函数定义上方加上 @repeat(3)@make_italic@make_bold,表示首先将 say_hello 函数传递给 repeat(3) 函数,接着将返回的新函数传递给 make_italic 函数,最后将返回的新函数传递给 make_bold 函数,并返回增强后的新函数。

4. 总结

函数装饰器是 Python 中的高级编程技巧,可以在不改变原函数代码的情况下,增强函数的功能。在 Python 中,装饰器是一个函数,它可以接收一个函数作为参数,对这个函数进行修改或者增强,最后返回被修饰后的新函数。常用的装饰器有函数装饰器和类装饰器两种。函数装饰器可以带有参数,也可以多重装饰。在使用装饰器时,需要注意装饰器的顺序,因为多个装饰器的执行顺序是从上到下的。

后端开发标签