Python的@装饰器的作用小结

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装饰器,它接受一个函数作为参数,并且返回一个新函数wrapperwrapper函数记录下了函数的执行时间,并且调用原始函数。最后,它返回原始函数的返回值。

在使用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特性,能够让我们在不修改原始函数代码的情况下,为其添加额外的功能。通过本文的介绍,你可以更好地了解装饰器的用法和应用,并能够运用装饰器来优化你的代码。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签