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地址。 点击桌面右上角下拉框,点击“设置”按…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器
一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...