第四十七回 一丈青单捉王矮虎 宋公明二打祝家庄-强大而灵活的python装饰器

四面全是埋伏,宋江和众人一直绕圈跑不出去。正在慌乱之时,石秀及时赶到,教大家碰到白杨树就转弯走。走了一段时间,发现围的人越来越多,原来祝家庄以灯笼指挥号令。花荣一箭射下来红灯龙,伏兵自己就乱起来了。

宋江叫石秀引路,带大军到了村口,与山寨的第二波马军林冲、秦明汇合。第二天天亮,发现镇三山黄信被抓了。

宋江同花荣杨雄石秀带李家庄请李应帮忙。李应以有箭伤为由没有出来见面,拒收了礼物。杜兴说因为祝家庄打伤了我们,我们不会再去帮他。你们要提防扈家庄的一丈青扈三娘。另外祝家庄有两座庄门,要一起打才行。

这是宋江第一次带兵打仗,很好很强大,战术也灵活主动,就像Python编程里的修饰器一样,强大而灵活。

强大而灵活的python装饰器

一、概述

在Python中,装饰器是一种特殊类型的函数,它允许我们修改或增强其他函数的功能,而无需修改其源代码。装饰器在函数定义之后立即调用,并以函数对象作为参数。装饰器返回一个新的函数对象,这个新函数对象通常会“包装”或“装饰”原函数,并在调用时执行额外的操作。

二、基本用法

装饰器的基本语法是使用@符号,后面紧跟装饰器函数的名称。装饰器函数通常接收一个函数作为参数,并返回一个新的函数。

@decorator_function  
def my_function():  
    pass

在上面的代码中,decorator_function是一个装饰器,它接收my_function作为参数,并返回一个新的函数对象。这个新的函数对象在调用时会执行decorator_function中定义的代码,并在适当的时候调用my_function

三、装饰器函数

装饰器函数通常接收一个函数作为参数,并返回一个新的函数。装饰器函数内部的新函数通常会调用原函数,并在调用前后执行额外的操作。

def decorator_function(func):  
    def wrapper(*args, **kwargs):  
        # 在原函数执行前执行的代码  
        print("Before function call")  
          
        # 调用原函数  
        result = func(*args, **kwargs)  
          
        # 在原函数执行后执行的代码  
        print("After function call")  
          
        return result  
      
    return wrapper

四、使用装饰器

使用装饰器非常简单,只需在函数定义之前加上@符号和装饰器函数的名称即可。

@decorator_function  
def my_function():  
    print("Inside function")  
  
# 调用被装饰的函数  
my_function()

五、使用装饰器的测试示例

下面是一个使用装饰器来实现基准测试的示例:

import time  
from functools import wraps  
  
def benchmark(func):  
    """  
    基准测试装饰器,用于测量函数的执行时间。  
  
    参数:  
        func (callable): 要测试的函数。  
  
    返回:  
        callable: 装饰后的函数,它会打印原始函数的执行时间。  
    """  
    @wraps(func)  
    def wrapper(*args, **kwargs):  
        start_time = time.time()  
        result = func(*args, **kwargs)  
        end_time = time.time()  
          
        elapsed_time = end_time - start_time  
        print(f"执行 {func.__name__} 花费了 {elapsed_time:.6f} 秒")  
        return result  
      
    return wrapper  
  
# 示例函数,我们将对其应用基准测试装饰器  
@benchmark  
def example_function(n):  
    sum = 0  
    for i in range(n):  
        sum += i  
    return sum  
  
# 调用示例函数,装饰器会自动打印执行时间  
print(example_function(1000000))

在这个例子中,benchmark 是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数 wrapperwrapper 函数会记录开始和结束时间,然后调用原始函数并打印出执行时间。@wraps(func) 是一个内置装饰器,用于保留原始函数的元信息(如函数名、文档字符串等)。

通过在 example_function 定义之前使用 @benchmark 装饰器,我们告诉Python在调用 example_function 时实际上要调用的是 wrapper 函数,而 wrapper 函数会记录并打印出 example_function 的执行时间。

使用装饰器的好处是你可以在不修改原始函数的情况下轻松添加新功能,例如基准测试。这使得代码更加模块化且易于维护。

六、装饰器的高级用法

1、多个装饰器

一个函数可以同时使用多个装饰器,只需在函数定义前依次列出它们即可。

@decorator1  
@decorator2  
def my_function():  
    pass

2、带参数的装饰器

装饰器本身也可以接收参数,并在内部定义装饰器函数。

def outer_decorator(param):  
    def decorator_function(func):  
        def wrapper(*args, **kwargs):  
            print(f"Before function call with param: {param}")  
            result = func(*args, **kwargs)  
            print(f"After function call with param: {param}")  
            return result  
          
        return wrapper  
      
    return decorator_function  
  
@outer_decorator("hello")  
def my_function():  
    print("Inside function")  
  
my_function()

七、注意事项

  • 装饰器会改变函数的名称和文档字符串,除非使用@wraps装饰器来保留这些信息。
  • 装饰器会改变函数的签名,这可能会影响依赖于函数签名的工具或库。
  • 装饰器可能会增加函数的调用开销,因为每次调用被装饰的函数时,都会执行额外的代码。

八、总结

装饰器是Python中一种强大而灵活的工具,它允许我们在不修改函数源代码的情况下,为函数添加额外的功能。通过正确使用装饰器,我们可以提高代码的可读性、可维护性和可扩展性。

宋江亲自做前锋去打头阵。扈三娘从西边杀来,王矮虎迎战,被扈三娘抓了。秦明邓飞也被抓了,一丈青扈三娘来抓宋江,这时候杨雄石秀小李广花荣都赶到,大家混战在一起。一丈青紧追宋江,被林冲抓住了。

宋江让把扈三娘连夜送上梁山,由宋太公收管。宋江正发愁,吴用带领三阮和吕方、郭盛带五百人马赶到。吴用说恰好有个机会,打败祝家庄小菜一碟。

欲知后事如何,且听下回分解。

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

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

相关文章

仿牛客网项目---显示评论和添加评论功能的实现

这篇文章,我来介绍一下我的项目中的另外一个功能:显示评论和添加评论。 其实这两个功能都不怎么重要,我感觉最重要的应该是用户注册登录功能,这个也了解一下,知道这么一回事儿就好。 首先设计DAO层。 Mapper public …

LNMP架构介绍及配置--部署Discuz社区论坛与wordpress博客

一、LNMP架构定义 1、LNMP定义 LNMP(Linux Nginx Mysql Php)是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写;Linux系统下NginxMySQLPHP这种网站服务器架构。 Linux是一类Unix计算机操作系统的统称,是目…

Qt程序设计-指南针自定义控件实例

本文讲解Qt指南针自定义控件实例。 效果演示 创建指南针类 #ifndef COMPASS_H #define COMPASS_H#include <QWidget> #include <QWidget> #include <QTimer> #include <QPainter> #include <QPen> #include <QDebug> #include <QtMat…

【激光SLAM】基于已知位姿的构图算法 (Grid-based)

文章目录 地图分类概念 覆盖栅格建图算法栅格地图的特征数学描述假设 算法流程激光雷达的逆观测模型 计数(Count Model)建图算法概念数学描述观测模型地图估计 地图分类 概念 地图即为环境的空间模型。环境地图是机器人进行定位和规划的前提。定位可以用特征地图&#xff08;…

java-ssm-jsp房屋中介服务平台的设计与实现

java-ssm-jsp房屋中介服务平台的设计与实现 获取源码——》公主号&#xff1a;计算机专业毕设大全

28.HarmonyOS App(JAVA)多页签的实现(Tab)

HarmonyOS App(JAVA)多页签的实现&#xff08;Tab&#xff09; 页面可左右滑动&#xff0c;点击界面1,2,3切换到对应界面 PageSlider的创建和使用 在layout目录下的xml文件中创建PageSlider。 <PageSlider ohos:id"$id:page_slider" ohos:height"300vp&…

Java编程实战:小区管理系统的设计与实现

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

MySQL之索引详解

华子目录 索引概述优缺点 索引的原理索引的设计原则索引结构B-tree&#xff08;多路平衡查找树&#xff09;BtreeHash 为什么InnoDB存储引擎选择Btree&#xff1f;索引分类聚集索引选取规则 单列索引和多列索引前缀索引创建索引1.创建表时创建索引2.在已经存在的表上创建索引3.…

Muduo库核心代码及优秀编程细节剖析

一、前言&#xff1a; Muduo库是陈硕个人开发的Tcp网络编程库&#xff0c;支持Reactor模型。这篇博文对Muduo库中的Multi-reactor架构代码进行逻辑梳理&#xff0c;同时认真剖析了作者每一处精妙的代码设计思想。 目前我只重构并剖析了Muduo库中的核心部分&#xff0c;即Mult…

了解处理器

了解处理器 摘要写在前面1. 计算机简介1.1.计算机发展简史1.2.计算机分类1.3.PC机结构 2.初识处理器2.1.处理器的硬件模型2.2.处理器的编程模型2.3.处理器的分层模型2.4.如何选择处理器 3.指令集体系结构3.1.处理器编程模型3.2.指令集发展历程3.3.指令集分类3.4.汇编语言格式3.…

第三百七十六回

文章目录 1 .概念介绍2. 实现方法3. 示例代码 我们在上一章回中介绍了在页面之间共传递数据相关的内容&#xff0c;本章回中将介绍如何拦截路由.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1 .概念介绍 本章回中介绍的路由拦截是指在路由运行过程中&#xff0c;对路由做…

Java进阶(锁)——锁的升级,synchronized与lock锁区别

目录 引出Java中锁升级synchronized与lock锁区别 缓存三兄弟&#xff1a;缓存击穿、穿透、雪崩缓存击穿缓存穿透缓存雪崩 总结 引出 Java进阶&#xff08;锁&#xff09;——锁的升级&#xff0c;synchronized与lock锁区别 Java中锁升级 看一段代码&#xff1a; public class…

Python学习 day06(类、对象、构造方法、私有方法、继承

类 程序中数据的组织多种多样&#xff0c;如果我们简单用变量来记录&#xff0c;就会混乱、不统一&#xff0c;如下所示&#xff1a; 类比现实中的表格&#xff0c;我们可以用类来组织数据&#xff0c;如下&#xff1a; 类的定义和使用 类中的变量叫做成员变量&#xff0c;类中…

mysql,for循环执行sql

遇到一个问题&#xff0c;我需要模拟上百万数据来优化sql&#xff0c;线上数据down不下来&#xff0c;测试库又没有&#xff0c;写代码执行要么慢要么就是sql语句太长。 于是&#xff0c;直接用mysql自带的功能去实现&#xff01; 简单而简单 mysql可以for循环&#xff1f;没…

python中版本,操作系统等问题汇总

1. linux源码部署到windows 1.1ModuleNotFoundError: No module named pwd 这个问题&#xff0c;是因为源码是给linux的。这里在windows中&#xff0c;没有该命令。 解决方法之一&#xff0c;在相应的环境目录中&#xff0c;如图中<MetaGPTenv>虚拟环境中&#xff0c;在…

Unity 预制体与变体

预制体作用&#xff1a; 更改预制体&#xff0c;则更改全部的以预制体复制出的模型。 生成预制体&#xff1a; 当你建立好了一个模型&#xff0c;从层级拖动到项目中即可生成预制体。 预制体复制模型&#xff1a; 将项目中的预制体拖动到层级中即可复制。或者选择物体复制粘贴。…

可用于智能客服的完全开源免费商用的知识库项目

介绍 FastWiki项目是一个高性能、基于最新技术栈的知识库系统&#xff0c;专为大规模信息检索和智能搜索设计。利用微软Semantic Kernel进行深度学习和自然语言处理&#xff0c;结合.NET 8和MasaBlazor前端框架&#xff0c;后台采用.NET 8MasaFrameworkSemanticKernel&#xff…

微信小程序云开发教程——墨刀原型工具入门(安装以及基础使用教程)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

IO-DAY2

用发write、fread将一张随意图片修改成德国国旗 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> int main(int argc, char *argv[]) {FILE* fpfopen("./122.bmp","r");int w 0,h 0;fseek(fp,18,…

队列的结构概念和实现

文章目录 一、队列的结构和概念二、队列的实现三、队列的实现函数四、队列的思维导图 一、队列的结构和概念 什么是队列&#xff1f; 队列就是只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有先进先出 如上图所示&#x…