当我们需要给已经存在的函数添加一些额外的功能,但是又不想修改已有函数的功能时,Python中的装饰器就是一个非常适合的工具。装饰器是一种返回函数的函数,它可以接受一个函数作为参数并返回一个新的函数来增强参数函数的功能。装饰器提供了一种方便的方式来修改函数,而不需要对原始函数的代码进行修改。
什么是装饰器
装饰器本质上是一个 Python 函数或类,可以使其他函数或方法在不需要做任何代码修改的前提下增加额外的功能。装饰器的返回值也是一个函数/类对象,它通常被用于“修饰”其他函数或类,因此装饰器也是一种基于闭包和函数式编程的设计模式。
装饰器的语法格式如下:
@decorator
def func():
pass
其中,decorator
是装饰器函数,func
是被修饰的函数。这种语法等同于:
func = decorator(func)
示例一:
def say_hello(func):
def wrapper():
print("Hello!")
func()
print("Nice to see you!")
return wrapper
@say_hello
def greet():
print("How are you?")
greet()
输出结果为:
Hello!
How are you?
Nice to see you!
在这里,我们定义了名为say_hello
的装饰器函数,它接受一个函数参数func
。在装饰器内部,我们定义了一个名为wrapper
的函数,它在调用func
之前和之后输出了一些内容。
然后,我们用装饰器来装饰greet
函数,即在greet
函数前加上@say_hello
。当我们调用greet
函数时,实际上执行的是wrapper
函数,它输出了Hello!
、How are you?
和Nice to see you!
。
示例二:
def bold(func):
def wrapper():
return "<b>" + func() + "</b>"
return wrapper
def italic(func):
def wrapper():
return "<i>" + func() + "</i>"
return wrapper
@bold
@italic
def hello():
return "Hello, World!"
print(hello())
输出结果为:
<b><i>Hello, World!</i></b>
在这里,我们定义了bold
和italic
两个装饰器函数。我们把这两个装饰器都应用在hello
函数上,即先执行italic
装饰器,再执行bold
装饰器。
当我们调用hello
函数时,实际上是在执行被bold
和italic
装饰过的wrapper
函数,返回结果<b><i>Hello, World!</i></b>
。
装饰器带参数
除了上面的示例中的不带参数的装饰器外,装饰器也可以带参数。例如,我们可以写一个装饰器,让其可以接受一个int类型的参数,表示要输出多少次“Hello!”。示例:
def say_hello_n_times(n):
def decorator(func):
def wrapper():
for i in range(n):
print("Hello!")
func()
print("Nice to see you!")
return wrapper
return decorator
@say_hello_n_times(3)
def greet():
print("How are you?")
greet()
输出结果为:
Hello!
Hello!
Hello!
How are you?
Nice to see you!
在这里,我们首先定义了一个带参数的装饰器函数say_hello_n_times
,它接受一个n
参数表示要输出多少次“Hello!”。在装饰器内部,我们定义了一个新的函数decorator
,它接受一个函数参数func
,并返回一个新函数wrapper
。
这个wrapper
函数在调用func
之前和之后输出了一些内容,并多次输出了“Hello!”,输出次数由参数n
指定。然后,我们使用@say_hello_n_times(3)
来装饰greet
函数,即表示要输出三次“Hello!”。当我们调用greet
函数时,它会输出三次“Hello!”、How are you?
和Nice to see you!
。
使用装饰器的注意事项
虽然装饰器是 Python 中非常有用的工具,但有一些使用注意事项,例如:
- 装饰器可以嵌套使用,但这也可能导致一些意外结果。
- 被装饰的函数的元信息会丢失。例如,函数名、文档字符串、注释等信息都会变为装饰器中内部函数的信息。
- 一些依赖函数签名的工具(例如某些IDE或编辑器)可能无法正确识别已装饰的函数的参数和返回值类型。
尽管有一些使用注意事项,但装饰器在 Python 中仍然是一种非常有用的工具,可以让我们更方便地修改已有函数的功能,提高代码可读性和可维护性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:通俗讲解python 装饰器 - Python技术站