1. @装饰器简介
在Python中,装饰器(Decorator)是一种函数,它可以接受一个函数,并且返回一个新函数。它的主要用途是在不改变原函数代码的情况下,为其添加额外的功能。Python中的@符号就是用来表示装饰器的。
Python的装饰器是一种元编程特性。元编程就是编写能自身创建、操作和操作函数的函数或代码。通过使用装饰器,我们就可以在运行中对一个函数的行为进行扩展或修改。
使用装饰器可以避免在函数内部修改代码,让我们能够通过增加样式或逻辑,独立于函数本身将功能加入到程序中。
装饰器是Python语言中比较高级的用法,因为它需要了解Python中函数是一等对象的概念。一等对象是指函数和变量一样可以作为参数传递和返回值的对象。
2. @装饰器的基础用法
2.1 装饰器的语法
装饰器的语法比较简单,可以通过下面的方式实现:
def decorator(func):
def wrapper(*args, **kwargs):
# 装饰器逻辑
return func(*args, **kwargs)
return wrapper
@decorator
def original_function():
# 原始函数逻辑
pass
上面的代码中,@decorator就是一个装饰器,它会将original_function
作为func
参数传递给decorator
函数。在decorator
函数中,我们定义了一个新函数wrapper
,它接受任意数目的位置参数和关键字参数,并且调用原始函数func
。最后,我们将wrapper
函数返回,以便它可以被后续调用。
由于上面的代码使用了@语法,所以我们可以写出更简洁的版本:
@decorator
def original_function():
# 原始函数逻辑
pass
这样的代码更简洁明了,使得代码的可读性更强。
2.2 装饰器的实例
下面,我们来看一个装饰器的实例。假设我们要在每次调用一个函数时记录下函数的执行时间,我们可以使用下面的装饰器:
import time
def time_it(func):
def wrapper(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print(f'{func.__name__} 执行时间:{end-start}s')
return result
return wrapper
@time_it
def my_func(n):
sum = 0
for i in range(n):
sum += i
return sum
my_func(1000)
上面的代码中,我们定义了一个time_it
装饰器,它接受一个函数作为参数,并且返回一个新函数wrapper
。wrapper
函数记录下了函数的执行时间,并且调用原始函数。最后,它返回原始函数的返回值。
在使用time_it
装饰器时,只需要在my_func
函数上加上@time_it
即可。当我们调用my_func
函数时,装饰器会自动记录下函数的执行时间,并且在函数执行结束后打印出来。
3. @装饰器的进阶用法
3.1 可传参数的装饰器
装饰器本身是一个函数,所以我们可以传递任意数目的参数给它。如果我们想要传递参数给装饰器,可以使用下面的语法:
def decorator(*args, **kwargs):
def wrapper(func):
# 装饰器逻辑
return wrapper
这样,decorator
函数就可以接受任意数目的位置参数和关键字参数。在这个函数内部,我们定义了一个新函数wrapper
,它接受一个函数作为参数。
下面,以一个实例说明可传参数的装饰器。
def repeat(num):
def decorator(func):
def wrapper(*args, **kwargs):
for i in range(num):
func(*args, **kwargs)
return wrapper
return decorator
@repeat(num=3)
def say_hello(name):
print(f'Hello, {name}!')
say_hello('Python')
3.2 带参数的原始函数装饰器
在上面的装饰器实例中,我们的原始函数没有参数。实际上,我们也可以定义带参数的原始函数,只需要在wrapper
函数中传递参数即可。
下面是一个带参数的装饰器的实例。
def my_decorator(func):
def wrapper(*args,**kwargs):
print(f'Function Name: {func.__name__}')
print(f'Arguments: {args}, {kwargs}')
return func(*args,**kwargs)
return wrapper
@my_decorator
def my_func(a,b,c):
return a+b+c
result = my_func(1,2,3)
print(f'Result: {result}')
上面的代码中,my_decorator
装饰器接受一个函数作为参数。在wrapper
函数中,我们打印了函数名和参数值,并且调用原始函数。最后,返回原始函数的返回值。
4. @装饰器的应用
4.1 日志记录
在程序中记录日志是一项很重要的任务,它可以帮助我们查找和解决各种程序错误。使用装饰器,可以轻松地为程序中的每个函数添加日志记录。
import logging
logging.basicConfig(level=logging.INFO)
def log_it(func):
def wrapper(*args,**kwargs):
logging.info(f'Call {func.__name__} Function')
return func(*args,**kwargs)
return wrapper
@log_it
def my_func(a,b,c):
return a+b+c
result = my_func(1,2,3)
print(f'Result: {result}')
在上面的代码中,我们定义了log_it
装饰器,它为每个函数添加了日志记录功能。通过使用装饰器,我们不需要在每个函数中添加日志记录代码。
4.2 授权限制
在程序中,我们有时需要对一些函数进行授权限制。可以使用装饰器来实现这个功能。
def auth_it(func):
def wrapper(*args,**kwargs):
username = input('Enter Your Username>>> ')
password = input('Enter Your Password>>> ')
if username == 'Admin' and password == '123456':
result = func(*args,**kwargs)
return result
else:
return 'You are not authorized to access this function!'
return wrapper
@auth_it
def my_func(a,b,c):
return a+b+c
result = my_func(1,2,3)
print(f'Result: {result}')
在上面的代码中,我们定义了auth_it
装饰器,它会在每次调用函数时要求用户输入用户名和密码。如果用户名和密码验证通过,则调用原始函数。否则,返回错误信息。
4.3 计时器
使用装饰器,我们可以为函数添加计时器,在函数执行结束后打印出函数的执行时间。
import time
def stopwatch(func):
def wrapper(*args,**kwargs):
start_time = time.time()
result = func(*args,**kwargs)
end_time = time.time()
print(f'{func.__name__} took {end_time-start_time:.4f}s')
return result
return wrapper
@stopwatch
def my_func(a,b,c):
return a+b+c
result = my_func(1,2,3)
print(f'Result: {result}')
在上面的代码中,我们定义了stopwatch
装饰器,用于计算函数执行时间。装饰器使用time.time()
函数来获取函数开始和结束的时间戳。在函数执行结束后,装饰器会计算函数执行的总时间,并打印出来。
5. 总结
本文介绍了Python中的装饰器,包括装饰器的基础用法和进阶用法。基础用法包括装饰器的语法和装饰器的实例。进阶用法包括带参数的装饰器和带参数的原始函数的装饰器。本文还介绍了装饰器的应用,包括日志记录、授权限制和计时器。
装饰器是一种高级的Python特性,能够让我们在不修改原始函数代码的情况下,为其添加额外的功能。通过本文的介绍,你可以更好地了解装饰器的用法和应用,并能够运用装饰器来优化你的代码。