手撕Python之生成器、装饰器、异常

1.生成器
生成器的定义方式:在函数中使用yield
yield值:将值返回到调用处
我们需要使用next()进行获取yield的返回值
yield的使用以及生成器函数的返回的接收next()
def test():yield 1,2,3t=test()
print(t)
#<generator object test at 0x01B77A48>
#生成器对象的意思#我们在函数中使用这个yield关键字,那么这个函数就是一个生成器函数#t存放的是生成器对象的信息
#yield的作用类似于return 将值返回到调用的地方#我们如何获取这个1呢?#next(生成器对象)
print(next(t))
#(1, 2, 3)#yied返回的内容我们需要通过next()进行一个获取的操作
有yiled的函数被称为生成器函数
对于性质一来说的话,yield会将后面的数据进行返回,返回到调用处
对于性质二的话,我们运行完yield之后,这个函数的运行位置就会被记录下来了
然后我们在交互模式再次进行这个next()的使用,进行返回值的获取那么就会从上次函数中结束的位置进行开始寻找数据然后进行返回的操作
然后后面如果没有yield的话,有个print('abc')
那么这个函数会将abc进行返回的,但是最终会进行报错的
就像下图所示
从下面的图片我们可以看的出什么呢?
def test():yield 1,2,3print('abc')yield 'a'
t=test()
print(t)print(next(t))
#(1, 2, 3)
print(next(t))
'''
abc
a
'''
我们在编辑模式第一次调用next()的时候打印出的返回值是1 2 3
我们在函数中又添加了一个yield关键字
然后我们在交互模式再次进行next的调用
这次的返回值是abc a
我们在调用next()的时候,这个我们会回到上一次yield结束的后面的一个位置
然后从那里开始寻找关键字yield进行数据的返回的操作
next()的作用就是获取yield后面的内容的
我们每次调用的时候就会回到上次yield结束的位置,从那个位置开始
yield和return的区别就是return会直接将函数进行结束,但是yield会保留此次的位置,下次调用的时候就从这个位置开始进行
yield只会中断,但是不会进行结束的操作
def testa():for i in range(1,10):yield it1=testa()
#获取yield返回值的方式:next()
print(next(t1))
#每次获取一个值,有多少个值就获取多少次
print(next(t1))
print(next(t1))
print(next(t1))
print(next(t1))
print(next(t1))
print(next(t1))
'''
1
2
3
4
5
6
7
'''
#如果我们超出了了的话就是会报错了
#因为最后一个yield后面没有数据了t2=testa()
#获取yield返回值的方法二
for n in t2:print(n)#我们通过for循环能够一次性拿完#我们通过next()的时候我们需要的时候就可以进行调用,想拿几个就拿几个print(next(t1))
#8
#我们需要用的时候就进行调用一下,不用就放着
对于获取yield我们有两种方法的,第一种就是进行Next函数的调用
第二种就是利用for循环,直接将对象当做条件进行循环,将这个函数中所有的yield后面的值进行返回
我们对于第一种的话,想什么时候用就什么时候用,随时能够进行调用的操作
2.装饰器
装饰器本质上是一个Python函数(其实就是闭包),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象
'''在不改动函数的情况下,给函数添加内容
装饰器的定义:
1.嵌套函数
2.外函数返回内函数名
3.外函数中定义一个形参,形参用来接受被装饰的函数名信息
4.要添加的额外功能,写在内函数中调用函数:函数名()使用装饰器:@装饰器名(外部函数名)
'''
#定义装饰器
def funa(name):def funb():print('---开始执行函数---')#在这个中间执行被装饰的函数name()#这个形参是用来接受这个被装饰的函数名的信息'''name=testcname()=testc()'''print('---函数执行完毕---')return funb#被装饰的函数
@funa
def testc():print('执行testc函数')testc()'''
---开始执行函数---
执行testc函数
---函数执行完毕---
'''
@funa
def testd():print('执行testd函数')
testd()
'''
---开始执行函数---
执行testd函数
---函数执行完毕--
'''
我们先进行装饰器的定义操作
1.嵌套函数
2.外函数返回内函数名
3.外函数中定义一个形参,形参用来接受被装饰的函数名信息
4.要添加的额外功能,写在内函数中
5.在内部函数中调用被装饰的函数,即外函数的函数名
我们的外函数有个形参name就是用来接受被装饰函数的函数名信息的
方便我们在内函数中进行调用
我们在被装饰的函数的定义上面加上 @外部函数名
那么就说明我们这个函数就已经被装饰好了
那么我们对testc进行调用的操作,那么就会运行我们之前在内部函数中做的装饰代码
总结:我们先会执行这个 @funa
@后面跟的是一个装饰器函数
然后就直接将这个testc的内容给到了name
给到name 之后我们就往后面走
执行内部函数,这个name=装饰的函数的函数名
我们先运行到@funa
然后就运行到def testc()
然后就def funa(name)
然后就运行到def funb()
运行到这个内部函数的时候
我们会直接返回这个funb()返回到被装饰的函数
就是返回到testc这里
那么到这里的话装饰就完成了
然后就直接跳到了testc()的带调用处
然后进行testc的调用的时候
我们就会直接调用装饰器内部函数
我们跳到testc()的地方的时候我们直接进行装饰器的内部函数的调用操作了
对于函数装饰的代码我们写在内部函数中
外部函数一定要定义形参,接受被装饰函数的函数名
不然我们在内部函数中无法进行被装饰函数的调用
那么装饰器的作用:在不改变原函数的情况下对函数进行一系列的装饰操作
就是一个外包操作的升级版本
def log(u):def aaa(name,pwd):d={'123456':{'pwd':'1234'},'1234567':{'pwd':'12345'}}if name in d:if pwd==d[name]['pwd']:print("登录成功")#调用被装饰的函数u(name,pwd)#外部参数的形参是uelse:print("密码错误")else:print("用户不存在")return aaa#取款
@log
def get_money(name,pwd):print(f"取款1000")
#查询
def set_money(name,pwd):print(f"存款1000")get_money('1256','1234')#通过装饰器我们能减少代码冗余的效果
不改变函数代码的情况下,对函数增加一系列的操作
3.异常
异常的概念
异常是指程序在运行过程中发生的错误或者不正常的情况。当Python检测到一个错误时,解释器就无法继续执行了,反而出现一些错误的提示。
根据报错信息我们能找到报错的地方
常见的异常
对异常的预防(try、except、Exception、raise、assert)
当我们遇到异常的时候程序会终止执行,可能还会导致软件崩溃,遇到异常的解决方法:
-
预防:添加容错代码(代码过多代码冗余)
-
解决:添加捕获异常部分(try、expect)
num=input("请输入一个整数")#异常解决方案一:添加容错代码
if num.isdigit():#判断字符串是否都是数字num=int(num)
else:print('输入的不是整数')#异常解决方案二:捕获异常
try:#可能会报错的语句num=int(num)
except ValueError:#except异常类型---捕获对应的异常类型#捕获到异常,处理的语句print(f"输入{num}不是整型")
#报错的默认信息
except ValueError as v:#接受捕获的异常的报错信息print(v)
else:print("没有报错")
finally:print("异常处理完毕")
#invalid literal for int() with base 10: '1.5'
print(1234)#用except捕获到异常之后我们就在后面进行处理,提醒出现的异常#多个expect的关系是或的关系,他们只会执行一个的
except异常类型:
对用户进行提醒的代码
如果我们不知道对应的异常类型的话
我们就写Exception ---万能异常
能接收所有的错误信息
能代替所有异常类型
如果我们看默认报错的话,我们就这么写
except Exception as a:
print(f"错误{a}")
这后面字母a,你想起什么字母就写什么字母
这个存储的是错误信息
finally 的话,不管有没有异常,都会执行下面的代码的
except和else关系是或,只能执行一个
try后面必须有一个except
finally不管是否发生异常,始终都会执行
raise会主动抛出异常
函数在出现异常的时候会将异常返回至函数调用处,在调用处就能进行处理操作
raise 异常类型(异常描述信息)---抛出异常
在后面加上异常提示信息
raise的用法:
def test():tel=input("请输入手机号码")if not(tel.isdigit() and len(tel)==11):#号码写错的情况下就会进行下面的代码#将错误信息抛出raise ValueError("请输入正确的11位手机号码")try:test()
except Exception as e:print(e)
assert语句的格式:
assert测试条件,错误信息
断言语句是一种调试工具,用来测试某个断言条件,如果断言条件为真,则程序将继续正常执行;如果条件为假,则会引发AssertionError异常并显示相关错误信息
try:n=input("请输入数字")assert n.isdigit(),'只能输入数字'#断言异常的话就会提示后面的错误信息的
except AssertionError as a:print(a)
print('6')
assert n.isdigit(),'只能输入数字'
assert 判断条件 ,‘报错信息’
4.模块
模块的简介
Python中的模块,指的就是一个py文件。对于一个py文件,可以只用import来导入其中的代码
模块的使用:import 模块名
import keyword---查看关键字
import random---电脑产生随机值
模块的分类
-
内置模块:这类模块是Python自带的,可以直接导入使用。
-
第三方模块:也就是别人写好的一些模块,你要安装之后才可以用(先下载再导入使用 )。
3.自定义模块:自己在项目中定义的一些模块,注意自定义模块的时候命名要遵循标识符规定和变量的命名规范,并且不要与内置模块起冲突,否则将导致模块功能无法使用。
不能和内置模块冲突了
我们在同一文件夹中写一个py文件
然后在这个文件里面导入另一个文件
假设另外一个文件叫test.py
里面有个名字
我们在这个文件中写
import test
print(test.name)
我们需要先将test.py里面的代码运行进行保存
我们在别的文件才能进行调用
最好将这几个文件放到同一个目录之下
相关文章:

手撕Python之生成器、装饰器、异常
1.生成器 生成器的定义方式:在函数中使用yield yield值:将值返回到调用处 我们需要使用next()进行获取yield的返回值 yield的使用以及生成器函数的返回的接收next() def test():yield 1,2,3ttest() print(t) #<generator object test at 0x01B77…...

LabVIEW步进电机控制方式
在LabVIEW中控制步进电机可以通过多种方式实现。每种方法都有其独特的优缺点,适用于不同的应用场合。下面详细介绍几种常见的步进电机控制方式,并进行比较。 1. 开环控制(Open-Loop Control) 特点 通过定期发出脉冲信号来控制步进…...

vllm源码解析(五):LLM模型推理
八 模型推理细节探索 8.1 回顾下step的流程 def step(self) -> List[Union[RequestOutput, EmbeddingRequestOutput]]:# 多GPU并行推理时走AsyncLLMEngine分支。如果进入当前LLMEngine,性能会下降,这里会抛出异常。if self.parallel_config.pipeline_parallel_s…...

数学建模笔记——熵权法(客观赋权法)
数学建模笔记——熵权法[客观赋权法] 熵权法(客观赋权法)1. 基本概念2. 基本步骤3. 典型例题3.1 正向化矩阵3.2 对正向化矩阵进行矩阵标准化3.3 计算概率矩阵P3.4 计算熵权3.5 计算得分 4. python代码实现 熵权法(客观赋权法) 1. 基本概念 熵权法,物理学名词,按照信息论基本原…...

XGBoost算法-确定树的结构
我们在求解上面的w和obj的过程中,都是假定我们的树结构是确定的,因为当我们改变树中划分条件的时候,每个叶子节点对应的样本有可能是不一样的,我们的G和H也是不一样的,得到的最优w和最优obj肯定也是不一样的。 到底哪一…...

concurrentHashMap线程安全实现的原理
1. Segment 数组 ConcurrentHashMap 内部维护一个 Segment 数组,每个 Segment 都是一个小型的 HashMap。Segment 继承自 ReentrantLock,因此每个 Segment 都是一个可重入锁。 2. 并发级别 ConcurrentHashMap 在构造时可以指定并发级别(con…...

域名证书,泛域名证书,sni
文章目录 前言一、证书1.全域名证书2.泛域名证书 二、域名证书的使用1、浏览器请求域名证书流程对全域名证书的请求流程对泛域名证书的请求流程ssl client-hello携带server name 报文 2、浏览器对证书的验证流程 三、域名证书和sni 前言 本文介绍了泛域名证书和全域名证书的区别…...

Pytest夹具autouse参数使用。True表示会自动在测试中使用,而无需显式指定
1. 全局conftest文件日志记录功能 # 当前路径(使用 abspath 方法可通过dos窗口执行) current_path os.path.dirname(os.path.abspath(__file__)) # 上上级目录 ffather_path os.path.abspath(os.path.join(current_path,"../"))LOG_FILE_PATH f{ffather_path}/lo…...

Linux:归档及压缩
tar命令 • tar 集成备份工具 – -c:创建归档 – -x:释放归档 – -f:指定归档文件名称,必须在所有选项的最后 – -z、-j、-J:调用 .gz、.bz2、.xz 格式工具进行处理 – -t:显示归档中的文件清单 – -C:指定…...

jenkins 安装
jenkins安装 jenkins官网 中文网址 安装设置 所有jenkins版本 内存512M以上,10Gb磁盘;安装jdk,需要java8以上下载较新的版本,否则安装插件时可能报错版本过低 # 搜索java yum search java | grep -iE "jdk"# 安装jd…...

mysql学习教程,从入门到精通,MySQL 删除数据库教程(6)
1、MySQL 删除数据库 使用普通用户登陆 MySQL 服务器,你可能需要特定的权限来创建或者删除 MySQL 数据库,所以我们这边使用 root 用户登录,root 用户拥有最高权限。 在删除数据库过程中,务必要十分谨慎,因为在执行删除…...

C语言:刷题日志(2)
一.币值转换 输入一个整数(位数不超过9位)代表一个人民币值(单位为元),请转换成财务要求的大写中文格式。如23108元,转换后变成“贰万叁仟壹百零捌”元。为了简化输出,用小写英文字母a-j顺序代…...

微带结环行器仿真分析+HFSS工程文件
微带结环行器仿真分析HFSS工程文件 工程下载:微带结环行器仿真分析HFSS工程文件 我使用HFSS版本的是HFSS 2024 R2 参考书籍《微波铁氧体器件HFSS设计原理》和视频微带结环行器HFSS仿真 1、环形器简介 环行器是一个有单向传输特性的三端口器件,它表明…...

怎么仿同款小程序的开发制作方法介绍
很多老板想要仿小程序系统,就是想要做个和别人界面功能类似的同款小程序系统,咨询瀚林问该怎么开发制作?本次瀚林就为大家介绍一下仿制同款小程序系统的方法。 1、确认功能需求 想要模仿同款小程序系统,那么首先需要找到自己想要…...

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现
一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息࿰…...

0.91寸OLED屏幕大小的音频频谱,炫酷
(后文有详细介绍) 频谱扫描: 迷你音频频谱——频率扫描 音乐律动: 迷你音频频谱——频率扫描 迷你音频频谱——音乐2 迷你音频频谱——音乐3 一、简介 音频频谱在最小0.91寸OLED 屏幕上显示,小巧玲珑 二、应用场景 本…...

6. LinkedList与链表
一、ArrayList的缺陷 通过源码知道,ArrayList底层使用数组来存储元素,由于其底层是一段连续空间,当在ArrayList任意位置插入或者删除元素时,就需要将后序元素整体往前或者往后搬移,时间复杂度为O(n),效率比…...

Statcounter Global Stats 提供全球统计数据信息
Statcounter Global Stats 提供全球统计数据信息 1. Statcounter Global Stats2. Mobile & Tablet Android Version Market Share WorldwideReferences Statcounter Global Stats https://gs.statcounter.com/ Statcounter Global Stats are brought to you by Statcounte…...

Linux kernel中的dts dtsi dtb dtc dtb.img dtbo.img
1、问题 kernel与hsm会设置一些gpio,但是某些gpio会在kernel与hsm侧共同设置,导致最终的设置结果失败,将kernel侧在dts文件中设置的gpio注释掉之后,发现hsm设置gpio时还是失败 2、问题原因 因为dts文件不仅仅会影响kernel镜像&…...

微信小程序页面制作——个人信息
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...

使用C++11的`std::async`执行异步任务:实战指南
使用C11的std::async执行异步任务:实战指南 在现代软件开发中,异步编程是提高应用程序性能和响应速度的重要手段。C11引入了std::async,使得编写异步任务变得更加简单和直观。本文将详细介绍如何使用std::async执行异步任务,并提…...

【高阶数据结构】B树、B+树、B*树
B树、B树、B*树 1. 常见的搜索结构2. B树概念3. B树的插入分析4. B树的插入实现4.1 B树的节点设计4.2 B树的部分插入实现14.3 B树的查找4.4 B树的部分插入实现24.5 插入key的过程4.7 B树的插入完整代码4.8 B树的简单验证4.9 B树的删除4.10 B树的性能分析 5. B树6. B*树7. 总结8…...

HBuilderx中vue页面引用scss样式
scss为css样式的预编译器,引入了变量、嵌入、混合、集成、引入等功能,相对于css样式,实现了样式的编程,具有更灵活的样式编写模式。 那么在HBuilderx中,“.vue”格式页面如何调用scss样式呢?详细如下&#…...

粒子群算法原理的示例介绍
一:粒子群优化算法的介绍 粒子群优化算法(PSO)是一种基于群体智能的优化算法,于1995年提出。它受到鸟群狩猎行为的启发,通过模拟鸟群或鱼群的社会行为来进行问题的求解。 基本原理 粒子群算法中,每个解决…...

GNU/Linux - Open函数使用的O_CLOEXEC flag
在 Linux 中,“O_CLOEXEC ”标志与 “open ”系统调用一起使用,用于指定在使用 “exec ”系列函数(如 “execve”、“execl ”等)执行新程序时,“open ”返回的文件描述符应自动关闭。 In Linux, the O_CLOEXEC flag i…...

AWQ量化(Activation-aware Weight Quantization)
论文: AWQ: Activation-aware Weight Quantization for On-Device LLM Compression and Acceleration 中文解读: 深入理解AWQ量化技术 - 知乎 (zhihu.com) 动机:端侧设备用LLM,为了减少显存占用量,所以要用INT4量化&am…...

SprinBoot+Vue体育商品推荐的设计与实现
目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍:CSDN认证博客专家,CSDN平台Java领域优质…...

【Python基础】Python函数
本文收录于 《Python编程入门》专栏,从零基础开始,分享一些Python编程基础知识,欢迎关注,谢谢! 文章目录 一、前言二、函数的定义与调用三、函数参数3.1 位置参数3.2 默认参数3.3 可变数量参数(或不定长参数…...

【超简单】1分钟解决ppt全文字体一键设置
省流 ppt的全部字体需要在“幻灯片母版”里面,“自定义字体”去设置好标题与正文的字体之后才算全部设置完毕 “视图”---“幻灯片母版” 找到“字体”---“自定义字体” 设置好中文和西文的字体,都可以按照自己的选择来,保存即可 吐槽 之…...

数组与贪心算法——179、56、57、228(2简2中)
179. 最大数(简单) 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数。 注意:输出结果可能非常大,所以你需要返回一个字符串而不是整数。 解法一、自定义比较…...