Python教程:对于初学者,几个易懂的装饰器示例用法

news2024/12/27 10:56:12

装饰器是Python中的一个高级功能,它可以用来扩展或修改一个函数或方法的功能,而不需要修改其原始代码。装饰器本质上是一个函数,它接受一个函数作为参数,并返回一个新的函数对象。

装饰器通常用于添加与函数功能无关的额外功能,如日志记录、性能测试、事务处理、缓存和权限校验等。通过使用装饰器,我们可以将与函数功能无关的代码抽离出来,并继续重用。

使用装饰器可以让我们动态地添加功能到函数或方法中,而不需要修改其原始代码。这种动态添加功能的方式被称为“装饰器”(Decorator),提供一种简洁而优雅的方式来修改、扩展或包装函数,使代码更具可读性和可维护性。

1.写一个简单的装饰器:在这个例子中,我们定义了一个名为count_time的装饰器函数。这个函数接受一个函数作为参数,并返回一个新的函数对象wrapper。在wrapper函数中,记录函数的运行的时间 。
接下来,我们使用装饰器来修饰一个名为my_python的函数。我们通过在函数定义之前加上@count_time来应用装饰器。当调用my_python时,实际上是调用了被装饰器返回的wrapper函数。

import time

def count_time(func):
    def wrapper():
        t1 = time.time()
        func()
        t2 = time.time()
        # 保留5位小数
        print('运行时间为:{:.5} s'.format(t2 - t1))

    return wrapper

# 用语法糖@+函数名,就可以直接调用该函数了
@count_time
def my_python():
    time.sleep(1)
    print('我的Python教程,微信公众号:wdPython')


my_python()

# 我的Python教程,微信公众号:wdPython
# 运行时间为:1.0008 s

2.带有返回值的函数,如何写装饰器:下面代码中执行my_python函数后,有一个常量返回值888888,那么你在wrapper函数里面,也要加进去返回值,这样才能打印出my_python函数的返回值。

import time

def count_time(func):
    def wrapper():
        t1 = time.time()
        result = func()
        t2 = time.time()
        # 保留5位小数
        print('运行时间为:{:.5} s'.format(t2 - t1))
        return result
    return wrapper

# 用语法糖@+函数名,就可以直接调用该函数了
@count_time
def my_python():
    time.sleep(1)
    print('我的Python教程,微信公众号:wdPython')
    return 888888

constant = my_python()
print(constant)

输出内容 :

我的Python教程,微信公众号:wdPython
运行时间为:1.0003 s
88888

**3.函数带参数,如何写装饰器:**首先在my_python函数中,定义一个times参数,表示打印我的Python教程的次数。然后在wrapper函数里面,把*ags参数传进来。ags用于接收一个,可变数量的参数列表,可以一个,可以n个。

import time

def count_time(func):
    def wrapper(*ags):
        t1 = time.time()
        result = func(*ags)
        t2 = time.time()
        # 保留5位小数
        print('运行时间为:{:.5} s'.format(t2 - t1))
        return result
    return wrapper

# 用语法糖@+函数名,就可以直接调用该函数了
@count_time
def my_python(times):
    time.sleep(1)
    print('我的Python教程,微信公众号:wdPython\n'*times)
    return 888888

constant = my_python(3)
print(constant)

输出内容:

我的Python教程,微信公众号:wdPython
我的Python教程,微信公众号:wdPython
我的Python教程,微信公众号:wdPython

运行时间为:1.0007 s
888888

2.装饰器带参数:当我们的被装饰的函数是带参数的,此时要怎么写装饰器呢?…

import time
def my_decorator(name):
    def count_time(func):
        def wrapper(*args, **kwargs):
            t1 = time.time()
            func(*args, **kwargs)
            t2 = time.time()
            print(f'[{name}]执行时间为:', t2 - t1)
        return wrapper
    return count_time

@my_decorator(name='李白')
def libai():
    time.sleep(1)
    print('我是李白')

@my_decorator(name='杜甫')
def dufu():
    time.sleep(1)
    print('我是杜甫')

libai()
dufu()

输出内容:
我是李白
[李白]执行时间为:1.0057024955749512
我是杜甫
[杜甫]执行时间为: 1.002488374710083

4.类装饰器的用法:在装饰器内部,我们定义了__init__和__call__方法,它们分别在创建类实例和调用类实例时被调用。

import time

class my_decorator:
    def __init__(self, func):
        self.func = func
        print("执行类的__init__方法")

    def __call__(self, *args, **kwargs):
        # 添加装饰器的功能
        print('进入__call__函数')
        t1 = time.time()
        self.func(*args, **kwargs)
        t2 = time.time()
        print('运行时间为:{:.5} s'.format(t2 - t1))

@my_decorator
def my_python():
    print('我的Python教程,微信公众号:wdPython')
    time.sleep(1.02)

my_python()

输出内容

执行类的__init__方法
进入__call__函数
我的Python教程,微信公众号:wdPython
运行时间为:1.0219 s

5.类装饰器的传参

class my_decorator:
    def __init__(self, arg1, arg2):  # init()方法里面的参数都是装饰器的参数
        print('执行类Decorator的__init__()方法')
        self.arg1 = arg1
        self.arg2 = arg2

    def __call__(self, func):  # 因为装饰器带了参数,所以接收传入函数变量的位置是这里
        print('执行类Decorator的__call__()方法')

        def baiyu_warp(*args):  # 这里装饰器的函数名字可以随便命名,只要跟return的函数名相同即可
            print('执行wrap()')
            print('装饰器参数:', self.arg1, self.arg2)
            print('执行' + func.__name__ + '()')
            func(*args)
            print(func.__name__ + '()执行完毕')

        return baiyu_warp

@my_decorator('李白', '杜甫')
def demo(a, b, c):
    print('函数的参数:', a, b, c)

demo(10, 20, 30)

输出内容:
执行类Decorator的__init__()方法
执行类Decorator的__call__()方法
执行wrap()
装饰器参数: 李白 杜甫
执行demo()
函数的参数: 10 20 30
demo()执行完毕

完毕!!感谢您的收看

----------★★历史博文集合★★----------
我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1325972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

泛微OA C# 调用 WebAPI功能实现

泛微OA C# 调用 WebAPI功能实现 OA 在线文档地址1. 创建流程字段参数 mainData 简单说明字段表明细表2. 接口封装2.1 接口初始化2.2 接口注册2.3 获取Token2.4 拼装 Headers2.5 常用工作流方法2.5.1 创建2.5.2 删除2.5.3 撤回2.5.4 退回3. 接口调用OA 在线文档地址 Token认证 …

【C#】.net core 6.0 通过依赖注入注册和使用上下文服务

给自己一个目标,然后坚持一段时间,总会有收获和感悟! 请求上下文是指在 Web 应用程序中处理请求时,包含有关当前请求的各种信息的对象。这些信息包括请求的头部、身体、查询字符串、路由数据、用户身份验证信息以及其他与请求相关…

Windows如何安装使用TortoiseSVN客户端并实现公网访问本地SVN Server

文章目录 前言1. TortoiseSVN 客户端下载安装2. 创建检出文件夹3. 创建与提交文件4. 公网访问测试 前言 TortoiseSVN是一个开源的版本控制系统,它与Apache Subversion(SVN)集成在一起,提供了一个用户友好的界面,方便用…

一文吃透String

1.概览 String 被声明为 final,因此它不可被继承。 内部使用 char 数组存储数据,该数组被声明为 final,这意味着 value 数组初始化之后就不能再引用其它数组。并且 String 内部没有改变 value 数组的方法,因此可以保证 String 不…

苏宁易购商品详情API:电商实时数据

一、引言 在当前的电商行业中,数据是最为宝贵的资源之一。如何获取实时、准确的数据,对于电商业务的运营和优化至关重要。作为中国领先的电商平台之一,苏宁易购提供了丰富的API接口,其中包括商品详情API,以便第三方开…

AI文生图功能试用

使用边界AICHAT中的文生图功能,使用下面的文本描述: 春天,在大明湖畔,一个中国南方的,女人,皮肤白皙,长发飘逸,明亮眼睛,五官俊俏,在静静的临摹,…

【扩散模型】8、DALL-E2 | 借助 CLIP 的图文对齐能力来实现文本到图像的生成

文章目录 一、背景二、方法2.1 Decoder2.2 Prior 三、图像控制3.1 Variations3.2 Interpolations3.3 Text Diffs 四、探索 CLIP 的潜在空间五、文本到图像的生成5.1 先验的重要性5.2 人类评价5.3 多样性和保真性的平衡5.3 在 COCO 上对比 论文:DALLE.2 代码&#x…

PyQt6 QColorDialog颜色对话框控件

锋哥原创的PyQt6视频教程: 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计50条视频,包括:2024版 PyQt6 Python桌面开发 视频教程(无废话版…

在ClickHouse数据库中启用预测功能

在这篇博文中,我们将介绍如何将机器学习支持的预测功能与 ClickHouse 数据库集成。ClickHouse 是一个快速、开源、面向列的 SQL 数据库,对于数据分析和实时分析非常有用。该项目由 ClickHouse, Inc. 维护和支持。我们将探索它在需要数据准备以…

程序员的23大IONIO面试问题及答案

文章目录 1. 什么是IO流?2.java中有几种类型的流?3.字节流和字符流哪个好?怎么选择?4.读取数据量大的文件时,速度会很慢,如何选择流?5. IO模型有几种?6.阻塞IO (blocking…

c jpeg 理论霍夫曼 DC AC表,c程序实现正向逆向转换

此4张表是理论表,不是针对某张图片的特定表。如编码程序不统计生成某图片的专用霍夫曼表,应该也可用理论表代用编码。 1.亮度DC表 左边第一列是二进制位数,就是对此位数编码 中间一列是生成比特流的位数,右边是生成的比特流。 …

Thunderbolt 3 PCIe Expansion 扩展卡

计算机目前大部分都能够提供 Thunderbolt 3 接口了。 Thunderbolt 3 的传输速度更快,所以我们需要把 Thunderbolt 3 转换为 SAS HBA,但市场上没有这个转换设备。 后来我们发现有 Thunderbolt 3 PCIe Expansion,就是通过这个设备把 Thunderb…

Postgresql中PL/pgSQL的游标、自定义函数、存储过程的使用

场景 Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句: Postgresql中PL/pgSQL代码块的语法与使用-声明与赋值、IF语句、CASE语句、循环语句-CSDN博客 上面讲了基本语法,下面记录游标、自定义函数、存储过程的使用。 …

(企业 / 公司项目)代码生成器底层原理:模板框架freemarker

1.按照设置好的模板文件就能生成Java,vue文件,前后端都可生成。 2.也可以进行复杂Excel到处:可以转成xml,用xml来制作模板,在生成excel 3.需要批量生成格式固定的一类文件的需求也可以使用模板框架freemarker 首先引…

大数据时代,如何基于机密虚拟化技术构建数据安全的“基石”

云布道师 2023 年 10 月 31 日-11 月 2 日,2023 云栖大会在中国杭州云栖小镇举行,阿里云弹性计算产品专家唐湘华、阿里云高级安全专家刘煜堃、蚂蚁集团高级技术专家肖俊贤三位嘉宾在【云服务器 & 计算服务】专场中共同带来题为《大数据时代&#xf…

推荐几个好用的开源无代码/低代码开发平台

一、什么是无代码/低代码开发 无代码/低代码开发是一种可视化的应用程序开发方法,使用具有拖放组件和模型驱动逻辑组合的图形界面。无代码/低代码开发试图降低从软件技术平台、产品和服务中提取价值的进入壁垒。低代码开发平台被称为可视化集成开发环境&#xff08…

任意文件下载漏洞的利用思考

0x01 前言 任意文件下载漏洞作为最常见的WEB漏洞之一,在平常的渗透测试中经常遇到,但是很多人却并没有深入去想该如何利用这种漏洞,导致忽略了一些细节的信息。 0x02 传统利用 1) 下载配置文件连数据库 通过任意文件下载漏洞下载网…

美团外卖商超商品销量数据

美团外卖商超商品月销量 字段名 店铺id 店铺名称 商品id 商品名称 商品分类 规格名 原价 现价 月销 规格属性 描述 商品图片 含商家月销量

opencv入门到精通——图像的基本操作

目录 目标 访问和修改像素值 访问图像属性 图像感兴趣区域ROI 拆分和合并图像通道 为图像设置边框(填充) 目标 学会: 访问像素值并修改它们 访问图像属性 设置感兴趣区域(ROI) 分割和合并图像 本节中的几乎所有操作都主要与Numpy相…

生成对抗网络与人工智能的完美融合:创新、艺术与未来

导言 生成对抗网络(GAN)作为一种深度学习框架,以其独特的生成能力引起广泛关注。生成对抗网络(GAN)与人工智能的结合不仅在科学领域引起了巨大的关注,也在艺术、医学等多个领域催生了令人振奋的创新。本文将…