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 中,装饰器是一个函数,它可以接收一个函数作为参数,对这个函数进行修改或者增强,最后返回被修饰后的新函数。常用的装饰器有函数装饰器和类装饰器两种。函数装饰器可以带有参数,也可以多重装饰。在使用装饰器时,需要注意装饰器的顺序,因为多个装饰器的执行顺序是从上到下的。