可迭代对象,迭代器对象,异常操作
今日内容概要
- 常见内置函数02
- 可迭代对象
- 迭代器对象
- for循环的内部原理
- 异常处理
- for循环的本质(自己写代码模拟)
内容详细
常见的内置函数#
- help()查看注释信息
用法:
1.help(len)
2.def index():
'''1231231231231'''
pass
help(index)
- id() 返回一串相对于内存地址的数字
print(id('123'))
括号内可以是函数名、变量名、字符串
- int() 类型转换、进制转换
# 类型转换:
s = '123123'
s = int(s)
print(s,type(s))
# 进制转换
s = 123
print(bin(s)) # 0b1111011
print(int(0b1111011)) # 123
- isinstance() 判断数据类型
s = '123123'
print(type(s) is str) # True
'''上面这种方式在学了这个函数之后就不推荐使用了,别扭'''
print(isinstance(s,str)) # True
- pow() 幂指数
print(pow(10,2)) # 前面那个是自然数,后面的是幂,这句话就是求出10的二次方等于多少
- round() 四舍五入
print(round(111,1)) # 111
print(round(13.14,1)) # 13.1
print(round(13.36,1)) # 13.4
"""
如果第一个数是整数,不管要保留多少位,结果还是整数,不会给添加上小数点
"""
可迭代对象#
# 什么是迭代:
迭代其实就是更新换代,每一次迭代的过程都需要依赖于上一次的结果,目的通常是为了接近并到达所需的目标或结果。
eg:游戏的更新就是版本的迭代
# 单纯的循环不是迭代
import time
while True:
print(111)
time.sleep(0.2)
并没有根据上一次的结果而产生新的结果
# 迭代的样子
n = 1
while n < 10:
print(n)
n += 1
# 迭代取值
l1 = [1,2,3,4,5,6]
n = 0
while True:
print(l1[n])
n += 1
# 可以取值,但是会报错
# IndexError: list index out of range
# 3.哪些数据是可迭代对象?
依次列举并尝试调用__iter__方法即可
# 列表所学数据类型
i = 11 # 整型不是
f = 11.11 # 浮点型不是
s = 'jason' # 字符是
l = [1,2,3,4] # 列表是
d = {'name':'jason','age':18} # 字典是
t = (1,2,3,4) # 元组是
se = {1,2,3,4,5} # 集合是
b = True # 布尔值不是
f = open() # 文件是
def index():pass # 普通函数不是
# 可以看出,能够成为迭代器的对象都是可以使用for循环的
"""
属于可迭代对象的有
字符串、列表、字典、元组、集合、文件对象
可迭代对象其实就是为了后续迭代取值做准备
提供了不依赖于索引取值的方式
"""
迭代器对象#
"""
什么是可迭代对象?
内置有__next__方法的都可以称之为是可迭代对象
"""
# 迭代器对象的特征
含有__iter__方法和__next__方法
# 如何理解迭代器对象
迭代器对象能够极大的节省存储空间
eg:类似于哆啦A梦的口袋,不用的时候就是一个口袋面积,用的时候可以从中取出很多数据
类似于一个工厂,有需要时才给生产东西
类似于一个老母猪,想要猪仔就给你下一个
# 迭代器对象如何取值
调用__next__方法即可 如果取完了则会直接报错
而且__next__只能从左到右依次取值,不能循环取值
'''这是一种不需要索引取值的方式(for循环底层依据的就是迭代器对象)
有了迭代器对象才出现了针对字典和集合的迭代取值操作'''
# 定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__和next方法。
迭代取值与索引取值的对比#
1.索引取值
优势:可以反复获取相同的元素,并且没有固定的方向
劣势:只能支持有序的容器类型,无序的无法取值兼容性没有迭代取值高
2.迭代取值
优势:兼容所有的容器类型
劣势:取值的顺序永远都是从左往右,并且无法重复获取,取完了就没了
'''这种方法用的不多,一般都用for循环'''
'''迭代器里面的东西是固定的,每取一个就会少一个,取完就空了'''
迭代器很多对象补充说明
1.有很多上下方法都有简便写法 但不是全部
"""
__方法名__等价 方面名()
最常见的两个是
__iter__ inter()
__next__ next()
"""
print(l1.__iter__()) # <list_iterator object at 0x0000026D2D429470>
print(iter(l1)) # <list_iterator object at 0x0000026D2D429470>
print(l1.__next__()) # 1
print(next(l1)) # 2
2.有一些可迭代对象本身也是迭代器对象>>>:文件对象
3.可迭代对象调用一次__iter__方法编程迭代器对象 如果继续调用 结果还是迭代器对象本身
res = l1.__iter__()
res1 = l1.__iter__().__iter__().__iter__()
print(res,res1)
# <list_iterator object at 0x0000019BE5623748> <list_iterator object at 0x0000019BE5617278>
4.迭代取值的要求
l1 = [1, 2, 3, 4, 5, 6]
print(l1.__iter__().__next__()) # 1,每次都先产生一个新的迭代器对象然后取值
print(l1.__iter__().__next__()) # 1,每次都先产生一个新的迭代器对象然后取值
print(l1.__iter__().__next__()) # 1,每次都先产生一个新的迭代器对象然后取值
print(l1.__iter__().__next__()) # 1,每次都先产生一个新的迭代器对象然后取值
res = l1.__iter__() # 已经变成迭代器对象了
print(res.__iter__().__next__()) # 1,之后再调用还是自身
print(res.__iter__().__next__()) # 2
print(res.__iter__().__next__()) # 3
print(res.__iter__().__next__()) # 4
总结#
"""
1.可迭代对象实现了 __ iter __ 方法。
2.使用iter()函数判断可迭代对象更准确
3.任何序列都是可迭代对象
4.迭代器对象实现了 __ iter __ 和 __ next __方法。
5.迭代器是一个可以记住数据集里元素位置的对象,其内部有一个状态用于记录迭代所在的位置,以便下次迭代时候能取出正确的元素
"""
for循环内部原理#
l1 = [1, 2, 3, 4, 5, 6]
'''需求,不依靠for循环完成对列表元素的取值'''
res = l1.__iter__()
n = 0
while n <len(l1):
print(res.__next__())
n += 1
"""
for循环底层原理
for 变量名 in 可迭代对象
循环体代码
1. 会将in后面的数据调用__iter__()变成迭代器对象
为什么文件对象也可以for循环 因为本身就是迭代器对象,再次调用不变
2.针对产生的迭代器对象一次调用__next__()方法迭代取值
3.当值取完之后 会自动处理报错并退出循环
"""
# for 循环相当于:
res = l1.__iter__()
while True:
print(res.__next__())
异常处理#
什么是异常?
代码运行出错之后就是异常,一场会导致程序立刻停止
'''
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
一般情况下,在Python无法正常处理程序时就会发生一个异常。
异常是Python对象,表示一个错误。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
'''
异常信息的组成部分
Traceback (most recent call last):
File "/Users/jiboyuan/PycharmProjects/day16/05 异常处理.py", line 3, in <module>
name
NameError: name 'name' is not defined
1.line关键字所在的一行
用于提示代码哪一行出错了,点击蓝色字体可以直接定位到那一行
2.NameError错误的类型
代码的报错也可以分为很多类型
3.name 'name' is not defined
具体的报错原因,能够解决报错的答案,通常显示在最后一行
异常的分类
1.语法异常
通常是语法上的错误,一般指代码语法结构不完善,写了一半的语法(不被允许的低级错误)
2.逻辑异常
代码的逻辑出现了问题,出现了应该想办法解决(又叫BUG)
异常的类型(部分)
BaseException | 所有异常的基类 |
---|---|
SystemExit | 解释器请求退出 |
KeyboardInterrupt | 用户中断执行(通常是输入^C) |
Exception | 常规错误的基类 |
StopIteration | 迭代器没有更多的值 |
GeneratorExit | 生成器(generator)发生异常来通知退出 |
StandardError | 所有的内建标准异常的基类 |
ArithmeticError | 所有数值计算错误的基类 |
FloatingPointError | 浮点计算错误 |
OverflowError | 数值运算超出最大限制 |
异常处理操作#
'''有时候针对可能出错的代码,也可以自己提前写好处理措施'''
正常情况下代码出错,肯定是直接导致程序停止
但是也可以自己通过代码来处理,从而避免程序的停止
基本语法结构
try:
可能会出错的代码
except 错误的类型1 as e: # e指代的就是错误的提示信息
针对性的处理措施
except 错误的类型2 as e: # e指代的就是错误的提示信息
针对性的处理措施
except 错误的类型3 as e: # e指代的就是错误的提示信息
针对性的处理措施
...
错误类型
很多时候可能自己都不知道会报什么类型的错误
'''万能异常:常见的报错都可以照单全收'''
try:
可能会出错的代码
except Exception as e:
统一的处理措施
异常处理使用准则
异常处理使用尊则
1.被检测的代码越少越好
2.能尽量少用就尽量少用
异常处理了解#
结合else使用
当try检测的代码没有发生异常 正常运行完毕之后执行else的子代码
try:
可能会出错的代码
except Exception as e:
统一的处理措施
else:
可能会出错的代码没有出错,最后走else子代码
结合finally使用
无论try检测的代码是否有异常,最后都被执行finally子代码
try:
name
except Excepticon as e:
print(e)
finally:
print('无论try检测的代码是否有异常,最后都被执行finally子代码')
全部一起使用(报错,else,finally)
try:
可能会出错的代码
except Exception as e:
统一处理的措施
else:
print('没报错~~~')
finally:
print('错不错都执行')
断言
用于判断一个表达式,在表达式条件为 false 的时候触发异常。
断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况
name = 'tuzi'
assert isinstance(name,str)
主动报错
raise NameError('我就想出错')
"""
由于是主动报错,所以非常明确的知道错误的类型
"""
for循环的本质#
# 利用while与异常捕获,实现for循环的功能
l1 = [1,2,3,4,5]
res = l1.__iter__() # 转为可迭代对象
while True:
try:
print(res.__next__())
except StopIteration: # 报错类型
break # 结束循环
分类:
python函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?