Python之装饰器-带参装饰器
Python之装饰器-带参装饰器
带参装饰器
- @之后不是一个单独的标识符,是一个函数调用
- 函数调用的返回值又是一个函数,此函数是一个无参装饰器
- 带参装饰器,可以有任意个参数
- @func()
- @func(1)
- @func(1, 2)
def add(x, y):"""函数说明:参数说明返回值说明"""pass# 先写一段伪代码
add.__name__, add.__doc__# add的名字是什么,add的文档是什么
# 返回结果:('add', '\n 函数说明:\n \n 参数说明\n 返回值说明\n ')
help(add) # 查看帮助# add的名字是什么,add的文档是什么
# 返回结果:Help on function add in module __main__:# 返回结果:add(x, y)
# 返回结果: 函数说明:# 返回结果: 参数说明
# 返回结果: 返回值说明
import datetime # 导入datetime模块start = datetime.datetime.now() # 开始时间
end = datetime.datetime.now() # 结束时间
def logger(wrapped):def wrapper(*args, **kwargs):"wrapper +++"start = datetime.datetime.now()ret = wrapped(*args, **kwargs)delta = (datetime.datetime.now() - start).total_seconds()print("{} tooks {}s.".format(wrapped.__name__, delta))return retwrapper.__name__ = wrapped.__name__ # 通过这行,使装饰器装的更像wrapper.__doc__ = wrapped.__doc__return wrapper@logger # 等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y): # add = wrapper"add description~~"#time.sleep(2)return x + yprint(add(4, 5)) # 非侵入代码,完成了功能,并且好像从来没有装饰过一样
print(add.__name__, add.__doc__)# 此为无参装饰器,已次代码为例演示带参装饰器。
# 返回结果:add tooks 4e-06s.
# 返回结果:9
# 返回结果:add add description~~
# def update(wrapper, wrapped):
# wrapper.__name__ = wrapped.__name__ # 通过这行,使装饰器装的更像
# wrapper.__doc__ = wrapped.__doc__
# 可以通过函数来调用,因为重复使用,不需要每次都创建,写到函数外方便调用# def update(src, dest): # 见名知意,这样写,src=源,dest=目标
# dest.__name__ = src.__name__
# dest.__doc__ = src.__doc__# from functools import update_wrapper # python内置函数调用from functools import update_wrapper, wraps # 装饰器版本def logger(wrapped):@wraps(wrapped) # 装饰器版本def wrapper(*args, **kwargs):"wrapper +++"start = datetime.datetime.now()ret = wrapped(*args, **kwargs)delta = (datetime.datetime.now() - start).total_seconds()print("{} tooks {}s.".format(wrapped.__name__, delta))return ret#wrapper.__name__ = wrapped.__name__ # 通过这行,使装饰器装的更像#wrapper.__doc__ = wrapped.__doc__#update(wrapper, wrapped)#update(wrapped, wrapper)#update_wrapper(wrapper, wrapped) # 调用return wrapper@logger # 等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y): # add = wrapper"add description~~"#time.sleep(2)return x + yprint(add(4, 5)) # 非侵入代码,完成了功能,并且好像从来没有装饰过一样
print(add.__name__, add.__doc__)# 带参装饰器的对比解释版本
# 返回结果:add tooks 6e-06s.
# 返回结果:9
# 返回结果:add add description~~
from functools import update_wrapper, wrapsdef logger(wrapped):@wraps(wrapped) # 等价式 wrapper = wraps(wrapped)(wrapper) # partial function(偏函数)def wrapper(*args, **kwargs):"wrapper +++"start = datetime.datetime.now()ret = wrapped(*args, **kwargs)delta = (datetime.datetime.now() - start).total_seconds()print("{} tooks {}s.".format(wrapped.__name__, delta))return retreturn wrapper@logger # 等价式, add = logger(add) # logger应该等效为单参函数
def add(x, y): # add = wrapperreturn x + y@logger
def sub(x, y):return x - y#print(add(5, 4))
#print(sub(5, 4))
print(add.__name__, sub.__name__)# 函数,函数执行过程,函数作用域,形参,实参,解构,嵌套函数,LEGB、高阶,柯里化,闭包
# 返回结果:add sub
相关文章:
Python之装饰器-带参装饰器
Python之装饰器-带参装饰器 带参装饰器 之后不是一个单独的标识符,是一个函数调用函数调用的返回值又是一个函数,此函数是一个无参装饰器带参装饰器,可以有任意个参数 func()func(1)func(1, 2) def add(x, y):"""函数说明&…...

抖音IP属地怎么更改
抖音是一个非常受欢迎的短视频平台,吸引了无数用户在上面分享自己的生活和才艺。然而,随着快手的火爆,一些用户开始担心自己的IP地址会被他人获取,引起个人隐私风险。那么,抖音用户又该如何更改到别的地方呢࿱…...

Flutter 全局控制底部导航栏和自定义导航栏的方法
1. 介绍 导航栏在移动应用中扮演着至关重要的角色,它是用户与应用之间进行导航和交互的核心组件之一。无论是简单的页面切换,还是复杂的应用导航,导航栏都能够帮助用户快速找到所需内容,提升用户体验和应用的易用性。 在移动应用…...

检索增强生成(RAG)技术:实现流程、作用及应用案例
一. RAG简介 在自然语言处理(NLP)领域中,检索增强生成(Retrieval-Augmented Generation, RAG)技术巧妙地结合了信息检索与神经网络生成模型的力量,通过在生成过程中引入相关的外部信息,实现了在…...

Ubuntu安装和使用
Ubuntu 安装和配置 修改下载源 打开软件与更新, 选择其它站点, 选择中国, 选择阿里云源 谷歌中文输入法配置 Ctrl Alt T打开终端, 执行下述命令下fcitx框架 输入密码进行安装 sudo apt-get install -y fcitx-googlepinyinWin呼出菜单, 选择语言支持, 第一次打开会显示语言…...
【Unity】Stream最好用的Selfhost开源轻量服务
【背景】 有好几种场景的投屏或者远控应用希望实现,无论用哪种方式,都绕不开如何构建服务这一关。 【分析】 外网有很多直接付费使用的信令传输类型或是提供流服务的服务器,但我的目标场景是断绝外网的局域网,而且付费也总觉得…...
Web 常见的攻击方式有哪些?
常见的 Web 攻击方式有以下几种: 跨站脚本攻击(XSS 攻击) 跨站请求伪造(XSRF 攻击) SQL 注入 XSS 攻击 MDN 定义如下: 跨站脚本攻击(Cross-site scripting,XSS)是一…...
Rancher(v2.6.3)——Rancher部署Redis(单机版)
Rancher部署Redis详细说明文档]:https://gitee.com/WilliamWangmy/snail-knowledge/blob/master/Rancher/Rancher%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3.md#6rancher%E9%83%A8%E7%BD%B2redis ps:如果觉得作者写的还行,能够满足您的需求&#…...

stm32-模拟数字转化器ADC
接线图: #include "stm32f10x.h" // Device header//1: 开启RCC时钟,包括ADC和GPIO的时钟//2:配置GPIO将GPIO配置为模拟输入模式//3:配置多路开关将左边的通道接入到规则组中//4:配置ADC转…...
[Repo Git] manifests的写法
manifests是个啥 在Repo中manifests描述了Repo客户端的结构,也就是可以从manifests中知道各个模块的代码应该从代码管理仓库当中哪个位置去获取。 manifests的基本结构是一个Git存储库,在顶层目录中持有一个default.xml文件。 由于m…...
位置编码与长度外推
位置编码 位置编码从前到后包括:绝对位置编码、余弦位置编码、旋转位置编码、ALiBi相对位置编码。 1 绝对位置编码(Absolute Positional Encoding) 应用的模型:BERT、GPT等Transformer基础模型广泛使用绝对位置编码来处理序列数据。 算法思想:绝对位置编码通过为序列中的…...

Linux信号补充——信号发送和保存
三、信号的发送与保存 3.1信号的发送 必须有操作系统来保存信号,因为他是管理者; 信号给进程的task_struct发送信号,在task_struct中维护了一个整数signal有0-31位,共32个bit位;对于信号的管理使用的是位图结…...

Vue3 中应该使用 Ref 还是 Reactive?
一、引言 在Vue 3中,构建响应式数据结构是构建用户界面和交互体验的核心部分。而在创建这些响应式数据时,我们有两个主要工具:reactive和ref。选择使用哪一个,实际上取决于你的数据结构和访问需求。 reactive主要用于处理复杂的数…...

红外相机和RGB相机标定:实现两种模态数据融合
1. 前期准备 RGB相机:森云智能SG2-IMX390,1个红外相机:艾睿光电IR-Pilot 640X-32G,1个红外标定板:https://item.taobao.com/item.htm?_ujp3fdd12b99&id644506141871&spma1z09.2.0.0.5f822e8dKrxxYI 2.操作步…...

前端项目,个人笔记(五)【图片懒加载 + 路由配置 + 面包屑 + 路由行为修改】
目录 1、图片懒加载 步骤一:自定义全局指令 步骤二:代码中使用 编辑步骤三:效果查看 步骤四:代码优化 2、封装组件案例-传对象 3、路由配置——tab标签 4、根据tab标签添加面包屑 4.1、实现 4.2、bug:需要…...

【MySQL】2.MySQL数据库的基本操作
目录 数据库基本操作 查看数据库信息 查看数据库结构 显示数据表的结构(字段) 常用的数据类型 数据库管理操作 SQL语句概述 SQL分类 1.DDL:数据定义语言 1.1创建数据库和表 创建数据库 创建数据表 1.2删除数据库和表 删除数据表…...

常见技术难点及方案
1. 分布式锁 1.1 难点 1.1.1 锁延期 同一时间内不允许多个客户端同时获得锁; 1.1.2 防止死锁 需要确保在任何故障场景下,都不会出现死锁; 1.2.3 可重入 特殊的锁机制,它允许同一个线程多次获取同一个锁而不会被阻塞。 1.2…...
c#关键字 static
static 修饰符可用于声明 static 类。 在类、接口和结构中,可以将 static 修饰符添加到字段、方法、属性、运算符、事件和构造函数。 static 修饰符不能用于索引器或终结器 尽管类的实例包含该类的所有实例字段的单独副本,但每个 static 字段只有一个副…...
redis 如何保证数据同步(数据变化时)
redis 如何保证数据同步(数据变化时) 思路 1.新增、删除和修改都先对数据库进行操作,这时数据库的数据将域缓存中数据不同。 2.数据库进行变动后,返回结果,根据返回的结果判断数据库操作是否成功。 3.如果数据库操…...

Ubuntu18.04桌面版设置静态IP地址
引用: Ubuntu配置静态IP_ubuntu配置静态ip地址-CSDN博客 正文 默认Unbuntu 18.04 Desktop桌面版使用 netplan 管理网卡网络地址。使用Unbuntu 18.04 桌面版配置,可以通过桌面上的设置图标配置网卡的静态IP地址。 点击桌面右上角下拉框,点击“设置”按…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码
目录 一、👨🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...