今日内容概要
- 常见内置函数
- 可迭代对象
- 迭代器对象
- for循环内部原理
- 异常处理
- 异常处理实操
- 异常处理了解
- for循环的本质
- 迭代取值与索引取值的对比
今日内容详细
一、常见内置函数(补充)
1、内置函数之help()
- 用于查看注释信息
help(len)
2、内置函数之id()
- 返回的是一串相当于内存地址的数字
print(id('jason'))
3、内置函数之int()
- 多用于类型转换、机制转换
4、内置函数之isinstance()
- 多用于判断数据类型,返回值是布尔值
print(type('jason') is str) # 类型判断 别扭的很 不推荐
print(isinstance('jason', str)) # True
print(isinstance('jason', int)) # False
5、内置函数之pow()
- 幂函数
print(pow(10,2)) # 底数是10,指数是2,也就是10的平方
print(pow(10,3)) # 也就是10的三次方
6、内置函数之round()
- 用于四舍五入
- 需要注意的是括号内第一个数是需要进行四舍五入的数,括号内的第二个参数控制的是需要保留几位小数部分
print(round(11, 1)) # 第二个参数控制需要保留几位小数部分
print(round(12.29, 1))
print(round(11.59, 1))
7、内置函数之sum()
- 对元素类型是数值的可迭代对象中的每个元素求和
print(sum([11,2,2,3,4,3,2])) # 27
print(sum((1, 2, 3))) # 6
汇总如下:
二、可迭代对象
1、什么叫迭代?
- 迭代其实就是更新换代,每一次迭代的过程都需要依赖上一次的结果
例如游戏的更新其实就是版本的迭代
2、什么是可迭代对象?
- 内置有__iter__方法的都可以称之为是可迭代对象
- 具备__iter__方法的对象,就是一个可迭代对象
- 可以通过for …in…这类语句迭代读取一条数据给用户使用的对象
"""
1.大白话理解就是数据可以通过点的方式点出来__iter__
2.__iter__该类代码的读法>>>:双下iter方法
千万不要读成杠杠iter杠杠、杠杠iter
"""
"""
属于可迭代对象的有
字符串、列表、字典、元组、集合、文件对象
可迭代对象其实就是为了后续迭代取值做准备
提供了不依赖于索引取值的方式
"""
三、迭代器对象
1、什么是迭代器对象?
- 可迭代对象调用__iter__方法之后生成的结果就是迭代器对象
2、迭代器对象的特征
- 含有__iter__方法和__next__方法
3、如何理解迭代器对象
1)可迭代对象包含迭代器,迭代器对象能够极大的节省存储空间
2)如果一个对象拥有__iter__方法,其是可迭代对象;如果一个对象拥有next方法,其是迭代器。
3)定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__和next方法。
4)迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
4、迭代器对象如何取值
- 调用__next__方法即可 如果取完了则会直接报错!!!
- 需要知道的是for循环底层依据的就是迭代器对象
- 有了迭代器对象才出现了针对字典和集合的迭代取值操作
5、迭代器对象补充说明
# 1.有很多双下方法其实都有简便写法 但不是全部
"""
__方法名__ 等价 方法名()
最为常见的两个是
__iter__ iter()
__next__ next()
"""
# print(s.__iter__())
# print(iter(s))
# print(s.__len__())
# print(len(s))
# 2.有一些可迭代对象本身也是迭代器对象>>>:文件对象
# 3.可迭代对象调用一次__iter__方法编程迭代器对象 如果继续调用 结果还是迭代器对象本身
# res = s.__iter__()
# res1 = s.__iter__().__iter__().__iter__()
# print(res, res1) # <str_iterator object at 0x10762bdd8> <str_iterator object at 0x107636dd8>
# 4.迭代取值的要求
# print(s.__iter__().__next__()) # j 每次先产生一个新的迭代器对象然后取值
# print(s.__iter__().__next__()) # j 每次先产生一个新的迭代器对象然后取值
# print(s.__iter__().__next__()) # j 每次先产生一个新的迭代器对象然后取值
# print(s.__iter__().__next__()) # j 每次先产生一个新的迭代器对象然后取值
res = s.__iter__() # 已经变成迭代器对象了
print(res.__iter__().__next__()) # j 之后再调用还是自身
print(res.__iter__().__next__()) # a
print(res.__iter__().__next__()) # s
print(res.__iter__().__next__()) # o
四、for循环内部原理
"""
for循环底层原理
for 变量名 in 可迭代对象:
循环体代码
1.会将in后面的数据调用__iter__()变成迭代器对象
为什么文件对象也可以for循环 因为本身就是迭代器对象 再次调用不变
2.针对产生的迭代器对象依次调用__next__()方法迭代取值
3.当值取完之后 会自动处理报错并退出循环
"""
l1 = [11,22,33,44,55,66,77,88]
res = l1.__iter__()
while True:
print(res.__next__())
break
五、异常处理
1、什么是异常?
- 代码运行出错之后就是异常 异常会导致程序立刻停止,这也是我们以后在编程过程中需要极力避免的情况(异常的外号>>>:bug)
2、异常信息的组成部分
1)line表示的就是关键字所在的一行
用于提示你代码哪一行出错了 点击前面的蓝色字体可以直接定位,如果报错的信息很长 一般最后一个才是
2)NameError错误的类型
代码的报错也可以分为很多类型
3)name ‘name’ is not defined
具体的报错原因(就是解决报错的答案)
3、异常的分类
1)语法异常
不被允许的 如果出现了必须立刻改正
2)逻辑异常
可以允许的 如果出现了尽快修改即可
eg:代码动态获取到了一个字符串类型的数据但是调用了列表的内置方法
# 改bug其实就是在重新梳理你的思路
ps:有时候改bug是非常漫长且痛苦的 此时程序员尽量不要被打扰
"""
公司里面写代码的流程
1.程序员写完之后自己先大致测试
2.然后交给专门的测试人员去测试
"""
4、异常的类型(有很多,不一一列举)
eg:名字错误、索引错误、键错误、值错误……
六、异常处理实操
'''有时候针对可能会出错的代码 也可以自己提前写好处理措施'''
正常情况下代码出错 肯定是直接导致程序停止
但是也可以自己通过代码来处理 从而避免程序的停止
# 基本语法结构
try:
可能会出错的代码
except 错误的类型1 as e: # e指代的就是错误的提示信息
针对性的处理措施
except 错误的类型2 as e: # e指代的就是错误的提示信息
针对性的处理措施
except 错误的类型3 as e: # e指代的就是错误的提示信息
针对性的处理措施
...
# 错误类型
很多时候可能自己都不知道会报什么类型的错误
'''万能异常:常见的报错都可以照单全收'''
try:
可能会出错的代码
except Exception as e:
统一的处理措施
"""
学到这里 有很多同学心里很高兴 以后永远都不会写bug了
只需要在代码的开头加try 所有代码全部写带try的里面 之后万能结尾
这么做没有任何意义!!!
"""
##############################################
异常处理使用尊则
1.被检测的代码越少越好
2.能尽量少用就尽量少用
##############################################
七、异常处理了解
1、结合else使用
- 当try检测的代码没有发生异常 正常运行完毕之后执行else的子代码
try:
可能会出错的代码
except Exception as e:
统一的处理措施
else:
可能会出错的代码没有出错 最后走else子代码
2、结合finally使用
- 无论try检测的代码是否有异常 最后都会执行finally子代码
try:
name
except Exception as e:
print(e)
finally:
无论try检测的代码是否有异常 最后都会执行finally子代码
3、全部整合到一起使用
try:
name
except Exception as e:
print(e)
else:
print('没报错 好极了')
finally:
print('管你错不错 都执行')
4、断言(了解中的了解)
name = 'jason'
assert isinstance(name,str)
5、主动报错(需要掌握)
raise NameError('不爽 就要作!!!')
'''由于是主动报错 所以可以非常明确的知道错误的类型'''
八、for循环的本质
# 利用while与异常捕获 实现for循环的功能
info = {'name': 'jason', 'age': 18, 'pwd': 123}
# 1.先转换成迭代器对象
# res = info.__iter__()
res = iter(info)
# 2.迭代取值
while True:
# print(res.__next__())
try:
print(next(res))
except StopIteration as e:
# 结束while循环
break
九、迭代取值与索引取值的对比
1、索引取值
- 优势:可以反复获取相同的元素 并且没有固定的方向
- 劣势:只能支持有序的容器类型 无序的无法取值兼容性没有迭代取值高
2、迭代取值
- 优势:兼容所有的容器类型
- 劣势:取值的顺序永远都是从左往右 并且无法重复获取 去、取完就完了
真正底层的迭代取值后续可能很少用 一般都是for循环代替
迭代器里面的东西是固定的 每取一个就会少一个 取完就空了