什么是迭代
迭代其实就是更新换代,每一次迭代的过程都需要依赖于上一次的结果
n = 1
while 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__()) # e
print(res.__iter__().__next__()) # v
print(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 == 1
assert 1 == 2
# 断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况
抛出异常
使用 raise
语句抛出一个指定的异常
x = 10
if 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