python装饰器解析(关键点:高阶函数、嵌套函数)(参数化装饰器、类装饰器)

文章目录

  • Python装饰器解析
    • 什么是Python装饰器
      • 基础理解
    • 如何创建装饰器(关键点:高阶函数、嵌套函数)
      • 创建基础装饰器
    • 使用装饰器
      • 使用示例
    • 装饰器的返回值
    • 参数化装饰器
      • 创建参数化装饰器
        • 语法示例
        • 使用示例
    • 类装饰器
      • 创建类装饰器
        • 语法示例
        • 使用示例

Python装饰器解析

Python装饰器是一个非常强大的工具,可以帮助我们以简洁的方式修改函数和类的行为。本文将对Python装饰器进行深入探讨,包括装饰器的基本概念、创建装饰器、使用装饰器以及如何处理更复杂的装饰器用例。

什么是Python装饰器

在Python中,装饰器基本上是一个函数,它接受一个函数作为输入并返回一个新的函数。

基础理解

def my_decorator(func):
    def wrapper():
        print("Before function execution")
        func()
        print("After function execution")
    return wrapper

def say_hello():
    print("Hello!")

say_hello_ = my_decorator(say_hello)
say_hello_()

运行结果:

在这里插入图片描述

这里,my_decorator就是一个装饰器。它接收一个函数say_hello作为输入,并返回了一个新的函数wrapper。

如何创建装饰器(关键点:高阶函数、嵌套函数)

Python装饰器的创建有两个关键要点:1) 高阶函数;2) 嵌套函数。高阶函数表示函数可以接受其他函数作为参数,或者返回一个函数作为结果。嵌套函数表示在一个函数内部可以定义另一个函数。

创建基础装饰器

def my_decorator(func):
    def wrapper():
        print("Before function execution")
        func()
        print("After function execution")
    return wrapper

使用装饰器

在Python中,使用装饰器非常简单,只需要在你想要“装饰”的函数上方添加@装饰器名即可。

使用示例

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

这段代码的执行效果与前面通过直接调用装饰器并将其赋值给原函数的方式是完全相同的。

装饰器的返回值

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
encoding = 'utf-8'


def timer_decorator(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} seconds to run.")
        return result
    return wrapper


@timer_decorator
def long_running_operation():
    time.sleep(2)
    return 'sleep complete'


print(long_running_operation())

运行结果:
在这里插入图片描述

这里,timer_decorator就是一个装饰器。它接收一个函数long_running_operation作为输入,并返回了一个新的函数wrapper

参数化装饰器

在很多情况下,我们希望我们的装饰器能够接受参数,以便我们能够对其行为进行更细粒度的控制。这就引出了所谓的参数化装饰器。

创建参数化装饰器

语法示例

这个装饰器用来重复执行函数指定次数:

def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat
使用示例
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
encoding = 'utf-8'


def repeat(num_times):
    def decorator_repeat(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator_repeat


@repeat(3)  # 表示要重复执行3次
def greet(name):
    print(f"Hello {name}")


greet("Alice")

在这里插入图片描述

类装饰器

除了函数装饰器,Python还支持类装饰器。类装饰器主要依赖于函数__call__(),每当你调用一个类的示例时,函数__call__()就会被执行。

创建类装饰器

语法示例

下面这个类装饰器CountCalls的主要目的是跟踪某个函数被调用的次数。它通过覆盖__call__方法来实现这一点,每当装饰的函数被调用时,就会增加num_calls计数器的值,并打印出该函数已被调用的次数:

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"Call {self.num_calls} of {self.func.__name__!r}")
        return self.func(*args, **kwargs)
使用示例
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
encoding = 'utf-8'


class CountCalls:
    def __init__(self, func):
        self.func = func
        self.num_calls = 0

    def __call__(self, *args, **kwargs):
        self.num_calls += 1
        print(f"Call {self.num_calls} of {self.func.__name__!r}")
        return self.func(*args, **kwargs)


@CountCalls
def say_hello(name):
    print(f"Hello, {name}")


say_hello("Alice")
say_hello("Bob")

运行结果:

在这里插入图片描述

ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍
ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嘴尚绝卤味:健康卤味,未来餐饮市场的新星

随着人们生活水平的提高,对于吃的要求也越来越高。尤其是在快节奏的现代社会中,健康饮食成为了越来越多人的追求。在这种背景下,健康卤味这一新兴食品品类应运而生,成为了餐饮市场的新宠儿。 一、健康卤味的崛起 传统的卤味制作过…

MySQL find_in_set函数的深入解析与应用

theme: smartblue 在数据库操作中,我们经常会遇到需要处理以逗号分隔的字符串,并且需要根据这些字符串进行查询的情况。MySQL提供了一个非常实用的函数FIND_IN_SET()来处理这种特定的查询需求。本文将深入解析FIND_IN_SET()函数的使用方法,并…

SAP MIGO前台批次特性值增强(自动带出)<转载>

原文链接:https://blog.csdn.net/qq_45063256/article/details/128464411 增强点:程序LCTMSF3Z 在MIGO中点击批次右边的分类时,自动将该批次的批次特性值带出来。 现在打开程序LCTMSF3Z 该程序就只有一个FORM,首先切换到编辑…

docker内容整理

docker内容整理 docker的安装 检查之前是否安装过docker,如果有使用yum remove docker卸载 [rootwoniu ~]# yum remove docker \ > docker-client \ > docker-client-latest \ > docker-common \ > docker-latest \ > docker-latest-logrotate \ &g…

Android12之MediaCodec硬编解码调试手段(四十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只…

Java多线程技术二:线程间通信——join()方法的使用

1 概述 在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束,这时如果主线程想等待子线程执行完成后再结束,例如子线程处理一个数据,主线程要取到这个数据中…

如何入驻抖音本地生活服务商,门槛太高怎么办?

随着抖音本地生活服务市场的逐渐成熟,越来越多平台开始涉及本地生活服务领域,而本地生活服务商成了一个香窝窝,为了保护用户权益和平台生态,对入驻入驻抖音本地生活服务商的条件及审核也越来越严格,这让很多想成为抖音…

Mysql的索引详解

1.索引的分类 1.按照功能来分,可以分为主键索引、唯一索引、普通索引、全文索引 2.按照索引字段个数来分,可以分为单列索引、联合索引 3.按照物理实现方式来分,可以聚簇索引、非聚簇索引 2.适合添加索引的场景 1.具有唯一性约束的字段。 2…

Matlab论文插图绘制模板第129期—函数网格曲面图

在之前的文章中,分享了Matlab函数折线图的绘制模板: 函数三维折线图: 进一步,再来分享一下函数网格曲面图。 先来看一下成品效果: 特别提示:本期内容『数据代码』已上传资源群中,加群的朋友请自…

直击2023云栖大会-大模型时代到来:“计算,为了无法计算的价值”

2023年的云栖大会以“计算,为了无法计算的价值”为主题,强调了计算技术在现代社会中的重要性,特别是在大模型时代到来的背景下。 大模型时代指的是以深度学习为代表的人工智能技术的快速发展,这些技术需要大量的计算资源来训练和优…

算法设计与实现--动态规划篇

什么是动态规划算法 动态规划算法是一种求解复杂问题的方法,通过将原问题分解为相对简单的子问题来求解。其基本思想是将待求解的问题分解为若干个子问题(阶段),按顺序求解子阶段,前一子问题的解,为后一子…

uniapp:如何使用uCharts

目录 第一章 前言 第二章 安装插件uCharts 第三章 使用uCharts 第四章 注意 第一章 前言 需求:这是很久之前的一个项目的需求了,当时我刚接触app,有这么一个需求,在uniapp写的app项目中做一些图表统计,最开始以为…

设备巡检的内容有哪些?巡检注意事项及巡检要点?

本文将为大家讲解:设备巡检的内容有哪些?巡检注意事项及巡检要点? 每个制造型企业都有成百上千的设备需要定期的巡检。在生产制造加工类企业中,设备的巡检、维修及保养工作是保障生产安全和效率的重要内容之一。过去因为问题设备漏…

【零基础入门Python】Python If Else流程控制

✍面向读者:所有人 ✍所属专栏:零基础入门Pythonhttps://blog.csdn.net/arthas777/category_12455877.html Python if语句 Python if语句的流程图 Python if语句示例 Python If-Else Statement Python if else语句的流程图 使用Python if-else语句 …

MDK ARM环境下的伪指令的测试

目录 测试目标: 测试代码: 1. start.s 2. align.s 测试结果: 1 .ldr伪指令的测试结果: 2 .align伪操作测试结果: 结果分析: 测试目标: 熟悉ARM处理器的伪指令,本次实验主要来练习ldr伪指令和align…

Python代码部署的三种加密方案,其中一种你肯定不知道

文章目录 前言一、代码混淆二、代码打包三、代码编译3.1 pyarmor快速使用3.2 pyarmor进阶使用关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Python工具包②Python实战案例③Python小游戏源码五、…

Docker Image(镜像)——5

目录: Docker 镜像是什么镜像生活案例镜像分层生活案例为什么需要镜像镜像命令详解 镜像命令清单docker imagesdocker tagdocker pulldocker pushdocker rmidocker savedocker loaddocker historydocker importdocker image prunedocker build镜像操作案例 查找镜像…

02_W5500网络初始化

如何与W5500通信? 我们在W5500介绍中可以看到W5500支持SPI通信协议,如果对SPI通信协议还不太了解,请转 SPI数据帧: W5500 的 SPI 数据帧包括了 16 位地址段的偏移地址, 8 位控制段和 N 字节数据段。 如图所示…

10分钟带你学会python模块和包的使用

如果你用过 Python,那么你一定用过 import 关键字加载过各式各样的模块。但你是否熟悉 Python 中的模块与包的概念呢?或者,以下几个问题,你是否有明确的答案? 什么是模块?什么又是包?from matp…

Educational Codeforces Round 159 (Rated for Div. 2)(A~E)

A - Binary Imbalance 题意:给定一个01串,你能够在相邻相同字符中插入‘1’,在相邻不同字符中插入‘0’,求最终能否使得0的数量严格大于1的数量。 思路:可以发现,当出现了‘01’或者‘10’子序列时,能够无…