首页 > 编程语言 >python基础篇:什么是装饰器?装饰器有什么用?

python基础篇:什么是装饰器?装饰器有什么用?

时间:2023-03-25 09:00:09浏览次数:40  
标签:function 函数 python wrapper 器有 time my 装饰

上一篇介绍了python的函数,本文将介绍Python的装饰器,装饰器应用非常广泛,一定要好好掌握啊

什么是装饰器

装饰器是一种Python语言的特性,它允许在不修改已有函数的情况下,向函数添加额外的功能。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数。

装饰器应用场景

  • 记录函数的执行时间
  • 缓存函数的结果,以避免重复计算
  • 检查函数的参数是否合法
  • 为函数添加日志记录
  • 为函数添加事务处理
  • 为函数添加权限检查

简单的装饰器

以下是一个简单的装饰器的示例,它向函数添加了计时功能:

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print("Time elapsed: ", end_time - start_time)
        return result
    return wrapper

@timer
def my_function():
    time.sleep(2)

my_function()

在上面的示例中,timer是装饰器函数的名称。它接受一个函数作为参数,并返回一个新的函数wrapperwrapper函数计算函数执行的时间,并打印出来。@timer语法将my_function函数传递给timer装饰器,这意味着my_function函数将被timer装饰器包装。

my_function函数被调用时,它实际上是wrapper函数被调用。wrapper函数计算函数执行的时间,并打印出来。最后,wrapper函数返回my_function函数的结果。

这将打印Time elapsed: 2.000000238418579到控制台上。

带参数的装饰器

装饰器可以接受参数,以便在运行时自定义装饰器的行为。要创建带参数的装饰器,需要编写一个函数,该函数接受装饰器参数,并返回一个装饰器函数。

以下是一个带参数的装饰器的示例,它允许指定函数的重试次数:

import time

def retry(max_retries):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(max_retries):
                try:
                    result = func(*args, **kwargs)
                    return result
                except Exception as e:
                    print("Error:", e)
                    time.sleep(1)
            raise Exception("Max retries exceeded")
        return wrapper
    return decorator

@retry(max_retries=3)
def my_function():
    print("Trying...")
    raise Exception("Something went wrong")

my_function()

在上面的示例中,retry是带参数的装饰器函数的名称。它接受一个参数max_retries,并返回一个装饰器函数decoratordecorator函数接受一个函数作为参数,并返回一个新的函数wrapperwrapper函数尝试调用原始函数,如果发生异常,则等待1秒钟并重试,最多重试max_retries次。

@retry(max_retries=3)语法将my_function函数传递给retry装饰器,并指定max_retries参数为3。

my_function函数被调用时,它实际上是wrapper函数被调用。wrapper函数尝试调用原始函数,如果发生异常,则等待1秒钟并重试,最多重试3次。

这将打印以下内容到控制台上:

Trying...
Error: Something

@wraps()语法糖

@wraps()是一个装饰器,它用于将被装饰函数的元数据复制到装饰器函数中。这包括函数名称、文档字符串、参数列表等。使用@wraps()装饰器可以确保装饰器函数的元数据与原始函数的元数据相同,这对于调试和文档编写非常有用。

这个装饰器丢失了原来函数对象的一些属性,比如:__name____doc__等属性。使用wraps语法糖可以保留这些属性。

以下是一个使用@wraps()装饰器的示例:

from functools import wraps

def my_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print("Before function")
        result = func(*args, **kwargs)
        print("After function")
        return result
    return wrapper

@my_decorator
def my_function():
    print("Function called")

print(my_function.__name__)

总结

装饰器可以接受参数,以便在运行时自定义装饰器的行为。要创建带参数的装饰器,需要编写一个函数,该函数接受装饰器参数,并返回一个装饰器函数。

本文由mdnice多平台发布

标签:function,函数,python,wrapper,器有,time,my,装饰
From: https://www.cnblogs.com/alanlin/p/17254100.html

相关文章

  • Python推导式、迭代器与生成器
    列表推导式[表达式for局部变量名in可迭代对象][表达式for局部变量名in可迭代对象if条件]如:print([i**2foriinrange(1,10)])#[1,4,9,16,25,36,......
  • 用python中的列表构建一个pandas
    importpandasaspd#创建一个包含学生信息的列表students=[['Alice',20,80],['Bob',21,75],['Charlie',19,90],['Dave',18,65]]#将列表转换为Data......
  • bing写的一段python程序
      让ai写一个和chatgpt交互的程序。用户在控制台输入内容来交互。程序不一定能正常运行,但是可以参考如果prompt参数长度过长,可以将其分成多个部分,然后将每个部分......
  • [oeasy]python0115_西里尔字符集_Cyrillic_俄文字符编码_KOI_8859系列
    各语言字符编码回忆上次内容上次回顾了非ascii的拉丁字符编码的进化过程0-127是ascii的领域西欧、北欧语言大多使用拉丁字符由iso组织制定iso-8859-1北欧原来不是......
  • 商城网站毕业设计( Python +Vue)
    网站介绍基于python开发的电子商城网站,平台采用B/S结构,后端采用主流的Python语言进行开发,前端采用主流的Vue.js进行开发。这是给师弟开发的毕业设计。整个平台包......
  • Python爬虫实战:从零开始制作一个网络爬虫
    网络爬虫,又称网页蜘蛛、网页抓取器等,是一种从互联网上自动抓取网页数据的程序。Python是编写网络爬虫的最佳语言,因为它具有简洁的语法、丰富的库和强大的社区支持。本文将......
  • Python3之sqlalchemy
    1.SQLAlchemy介绍SQLAlchemy是Python中一款非常优秀的ORM框架,它可以与任意的第三方web框架相结合,如flask、tornado、django、fastapi等。SQLALchemy相较于Django......
  • python pandas timestamp
    #1.构造Timestamp#ts_input参数支持4种格式,datetime-like,str,int,float#1.1datetime-likeimportdatetimeimportpandasaspdtime_str="2020-08-0110:2......
  • 9个都要了解的单行Python代码
    当我们开始学习Python时,我们通常会优先编写能够完成工作的代码,而不会关注代码的可读性以及代码的简洁性和效率。确切来说,这是完全没有问题的,但是有一些方法可以在不忽略......
  • python 批量爬取邮箱
    python批量爬取邮箱地址#coding:utf-8importrequestsimportbs4#解析网页importlxmlimportreheaders={'User-Agent':'Mozilla/5.0(WindowsNT10.0;Win......