12步教你理解Python装饰器
什么是装饰器?
装饰器(Decorator)是Python中非常棒的一个特性,它可以让我们在不修改已有代码的前提下,动态增加函数的功能。本质上,装饰器是一个函数,它接受一个函数作为输入,然后返回一个新的函数作为输出。
装饰器的基本语法
@decorator
def func():
pass
如上所示,通过在函数定义前加上@decorator
,我们就可以让Python自动把函数传递给装饰器函数进行处理。
装饰器的实现
下面,我们来看一下如何实现一个简单的装饰器。假设我们要给一个函数打印执行时间:
import time
def time_it(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"函数{func.__name__}的执行时间为{end_time - start_time}秒")
return result
return wrapper
如上所示,我们先定义了一个time_it
函数,它接受一个函数作为参数,然后返回一个新的函数wrapper
。在wrapper
函数中,我们用time
模块计算了函数的执行时间,并打印出来。最后,我们返回了result
,即原函数的执行结果。
装饰器的使用
有了装饰器,我们现在可以很方便地给任意一个函数添加计时功能了:
@time_it
def my_func():
time.sleep(1)
print("Hello, world!")
my_func()
如上所示,我们在my_func
函数之前加上了@time_it
,这样my_func
传递给了time_it
函数进行处理。运行结果如下:
Hello, world!
函数my_func的执行时间为1.000929355621338秒
装饰器的高级用法
除了上面的简单用法,装饰器还有很多高级用法。比如说,我们可以给装饰器传递参数:
def repeat(n):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(n):
print(f"第{i + 1}次执行:")
func(*args, **kwargs)
return wrapper
return decorator
@repeat(3)
def hello():
print("Hello, world!")
如上所示,我们定义了一个repeat
函数,它接受一个参数n
,然后返回一个装饰器函数decorator
。在decorator
函数中定义了一个wrapper
函数,它会按照n
的值重复执行原函数。最后,在hello
函数之前加上了@repeat(3)
,这样hello
就被重复执行了3次。运行结果如下:
第1次执行:
Hello, world!
第2次执行:
Hello, world!
第3次执行:
Hello, world!
此外,我们还可以使用Python内置库functools
提供的wraps
装饰器来保留原函数的元信息:
from functools import wraps
def log_it(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(f"调用函数{func.__name__}")
return func(*args, **kwargs)
return wrapper
@log_it
def my_func():
print("Hello, world!")
print(my_func.__name__)
如上所示,我们在wrapper
函数外部加上了@wraps(func)
装饰器,并运行了my_func.__name__
。这样可以保留my_func
函数的元信息。运行结果如下:
my_func
装饰器的注意事项
最后,我们需要注意一些装饰器的注意事项:
- 装饰器只在模块加载时运行一次,而不是每次函数调用时都运行。
- 装饰器可以嵌套使用。
- 装饰器对函数的元信息有可能会改变,比如函数名和文件名。
结语
希望通过本文讲解,大家能够更好地理解Python装饰器的使用方法和实现原理。如果你还有其他疑问,欢迎留言讨论。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:12步教你理解Python装饰器 - Python技术站