什么是迭代
迭代其实就是更新换代,每一次迭代的过程都需要依赖于上一次的结果
n = 1while True:print(n)n+=1
什么是可迭代对象
内置有__iter__方法的对象都是可迭代对象,字符串、列表、元组、字典、集合、打开的文件都是可迭代对象(能for的都是可迭代对象)
i = 11 # 整型,不是f = 11.11 # 浮点型,不是s = 'jason' # 字符,是l = [1,2,3,4] # 列表,是d = {'name':'kevin','age':18} # 字典,是t = (1,2,3,4) # 元组,是se = {1,2,3,4,5} # 集合,是b = True # 布尔值,不是f = open() # 文件,是def index():pass # 普通函数,不是
补充:可迭代对象其实就是为了后续迭代取值做准备,提供了不依赖于索引取值的方式
什么是迭代器对象
可迭代对象调用__iter__方法之后生成的结果就是迭代器对象,迭代器对象是内置有__iter__和__next__方法的对象。执行迭代器__next__方法就会计算出迭代器中的下一个值,再次执行迭代器对象__iter__方法得到的仍然是迭代器本身。迭代器是Python提供的一种统一的、不依赖于索引的迭代取值方式,只要存在多个“值”,无论序列类型还是非序列类型都可以按照迭代器的方式取值
s = 'kevin'res = s.__iter__()print(res)# <str_iterator object at 0x7fd3e9257860>print(res.__next__())# k
补充:
__方法名__等价于方法名()(但不是全部),所以__iter__还可以写成iter(),__next__可以写成next()- 用
__next__取值,取完会报错 - 迭代器对象能够极大的节省存储空间
- 有一些可迭代对象本身也是迭代器对象,例如文件对象
- 可迭代对象调用一次
__iter__方法编程迭代器对象,如果继续调用结果还是迭代器对象本身
s = 'kevin'print(s.__iter__().__next__()) # k 每次先产生一个新的迭代器对象然后取值print(s.__iter__().__next__()) # k 每次先产生一个新的迭代器对象然后取值print(s.__iter__().__next__()) # k 每次先产生一个新的迭代器对象然后取值print(s.__iter__().__next__()) # k 每次先产生一个新的迭代器对象然后取值res = s.__iter__() # 已经变成迭代器对象了print(res.__iter__().__next__()) # k 之后再调用还是自身print(res.__iter__().__next__()) # eprint(res.__iter__().__next__()) # vprint(res.__iter__().__next__()) # i
迭代取值与索引取值的对比
索引取值
优势:可以反复进行取值,获取相同的元素,没有固定的方向
劣势:只能在有序的容器类型中取值,无序的无法取值兼容性没有迭代取值高
迭代取值
优势:兼容所有容器类型
劣势:取值永远都是从左往右,并且无法重复取值,取完就没了
异常处理
什么是异常
代码运行出错之后就是异常,异常会导致程序立刻停止 ,也就是bug
异常信息的组成部分
Traceback (most recent call last):File "/Users/kevin/Desktop/python/main.py", line 1, in <module>int('name')ValueError: invalid literal for int() with base 10: 'name'# 1. line -- 关键字所在的一行,用于提示你代码哪一行出错了# 2. ValueError -- 错误的类型,代码的报错也可以分为很多类型# 3. invalid literal for int() with base 10: 'name',-- 具体的报错原因(就是解决报错的答案)
异常的类型
| 异常名称 | 描述 |
|---|---|
| BaseException | 所有异常的基类 |
| SystemExit | 解释器请求退出 |
| KeyboardInterrupt | 用户中断执行(通常是输入^C) |
| Exception | 常规错误的基类 |
| StopIteration | 迭代器没有更多的值 |
| GeneratorExit | 生成器(generator)发生异常来通知退出 |
| StandardError | 所有的内建标准异常的基类 |
| ArithmeticError | 所有数值计算错误的基类 |
| FloatingPointError | 浮点计算错误 |
| OverflowError | 数值运算超出最大限制 |
| ZeroDivisionError | 除(或取模)零 (所有数据类型) |
| AssertionError | 断言语句失败 |
| AttributeError | 对象没有这个属性 |
| EOFError | 没有内建输入,到达EOF 标记 |
| EnvironmentError | 操作系统错误的基类 |
| IOError | 输入/输出操作失败 |
| OSError | 操作系统错误 |
| WindowsError | 系统调用失败 |
| ImportError | 导入模块/对象失败 |
| LookupError | 无效数据查询的基类 |
| IndexError | 序列中没有此索引(index) |
| KeyError | 映射中没有这个键 |
| MemoryError | 内存溢出错误(对于Python 解释器不是致命的) |
| NameError | 未声明/初始化对象 (没有属性) |
| UnboundLocalError | 访问未初始化的本地变量 |
| ReferenceError | 弱引用(Weak reference)试图访问已经垃圾回收了的对象 |
| RuntimeError | 一般的运行时错误 |
| NotImplementedError | 尚未实现的方法 |
| SyntaxError | Python 语法错误 |
| IndentationError | 缩进错误 |
| TabError | Tab 和空格混用 |
| SystemError | 一般的解释器系统错误 |
| TypeError | 对类型无效的操作 |
| ValueError | 传入无效的参数 |
| UnicodeError | Unicode 相关的错误 |
| UnicodeDecodeError | Unicode 解码时的错误 |
| UnicodeEncodeError | Unicode 编码时错误 |
| UnicodeTranslateError | Unicode 转换时错误 |
| Warning | 警告的基类 |
| DeprecationWarning | 关于被弃用的特征的警告 |
| FutureWarning | 关于构造将来语义会有改变的警告 |
| OverflowWarning | 旧的关于自动提升为长整型(long)的警告 |
| PendingDeprecationWarning | 关于特性将会被废弃的警告 |
| RuntimeWarning | 可疑的运行时行为(runtime behavior)的警告 |
| SyntaxWarning | 可疑的语法的警告 |
| UserWarning | 用户代码生成的警告 |
异常处理实操
捕捉异常可以使用try/except语句,try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理
基本语法结构
try:可能会出错的代码except 错误类型1 as i: # i指代的就是错误的提示信息,可以不写针对性的处理措施except 错误类型2 as i: # i指代的就是错误的提示信息,可以不写针对性的处理措施except 错误类型3 as i: # i指代的就是错误的提示信息,可以不写针对性的处理措施
try:int('name')except ValueError as e:print('kevin', e)# kevin invalid literal for int() with base 10: 'name'
万能语法结构
try:可能会出错的代码except Exception as i:统一的处理措施
结合else使用
try:可能会出错的代码except Exception as i:统一的处理措施else:可能会出错的代码没有出错 最后走else子代码
try:str('name')except Exception as i:print('错了')else:print('没有错')# 没有错
结合finally使用
try:int('name')except Exception as i:print('错了')finally: # 无论try检测的代码是否有异常 最后都会执行finally子代码print('没有错')# 错了# 没有错
断言
用于判断一个表达式,在表达式条件为 false 的时候触发异常
assert 1 == 1assert 1 == 2# 断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况
抛出异常
使用 raise 语句抛出一个指定的异常
x = 10if x > 5:raise Exception(f'x 不能大于 5。x 的值为: {x}')
for循环原理
原理
for 变量名 in 可迭代对象:循环体代码# 1. 会将in后面的数据调用__iter__()变成迭代器对象这就是为什么文件对象也可以for循环 因为本身就是迭代器对象 再次调用不变# 2. 针对产生的迭代器对象依次调用__next__()方法迭代取值# 3. 当值取完之后 会自动处理报错并退出循环
实现
l = [1, 2, 3, 4, 5, 6]l = iter(l)while True:try:print(next(l))except Exception:break
