手撕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的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
