异常捕获
# 1.如何理解异常
程序在运行的过程中如果出现了异常会导致整个程序的结束
异常就是我们口中的'bug'
# 2.异常的结构
''' Traceback (most recent call last):
File "/Users/xunfei/PycharmProjects/day21/异常捕获.py", line 1, in <module>
name
NameError: name 'name' is not defined '''
# 2.1.关键字line所在行
精准提示你哪一行代码出错
# 2.2.最后一行冒号左侧
是异常的类型
# 2.3.最后一行冒号右侧
错误的具体原因(关键)
# 3.异常的分类
3.1. 语法错误:不允许出现,一旦出现请立刻修改
3.2逻辑错误:允许出现,发现后修改
# ps: 写代码时,具体功能实现后先大致测一下,然后在提交
异常捕获实战演练
# 1.什么时候才可能会需要自己写代码处理异常
当代码不确定什么时候会报错的情况下需要自己写代码处理异常
比如编写网络爬虫访问网页数据并处理,有可能出现断网数据没有处理不了
# 2.异常捕获的使用相当于是提前预测可能出现的问题,并给出处理措施
# 3.异常捕获的代码实现
# 3.1基本语法结构
try:
name
# l1 = [1,2]
# l1[100] =100
except NameError as e:
print(e) # name 'name' is not defined
except IndexError as e:
print(e) # list assignment index out of range
...
# 3.2万能异常(笼统处理方式)
try:
# name
d= {'name':'jason'}
d['pwd']
# 123+'hello'
except Exception as e: # 万能异常处理方式1
print(e)
except BaseException as e: # 万能异常处理方式2
print(e)
# 4.异常捕获其他操作补充
# 4.1 else与finally
try:
# name
age = 18
except Exception as e:
print('程序出错了')
else:
print('程序如果不出错,会执行else代码')
finally:
print('不管程序出不出错,都会执行finally代码')
# 4.2 断言
name = 'jason' # 通过一系列的手段获取来的数据
assert isinstance(name,str) # 断言数据属于什么类型,如果不对就直接报错,对则正常执行下面代码
print('针对name数据使用字符串相关操作')
# 4.3 主动抛异常
name = input('username>>>:').strip()
if name == 'jason':
# raise NameError('jason来了,给他来个异常')
raise Exception('反正就是有异常')
else:
print('不是jason,正常执行程序')
# 5.强调
1.异常捕获能尽量少用就尽量少用
2.被try监测的代码能尽量少就尽量少
异常捕获练习
# 1.for循环内部的本质
l1 = [11,22,33,44,55,66,77]
res= l1.__iter__()
while True:
try:
print(res.__next__())
except Exception as e :
break
生成器对象
# 1.本质: 就是迭代器对象
只不过迭代器是解释器提供给我们的(现成的)
生成器是我们自己定义出来的
__iter__和__next__
# 2.目的:学习生成器对象的目的是为了优化代码
一种不依赖于索引取值的通用方式
可以节省数据类型的内存占用空间(主要)
# 3.实现
def index():
print('hello,python!')
yield 11,22,33
print('hello,mysql!')
yield 44
print('hello,redis!')
yield 55
"""
当函数体代码中有yield关键字
那么函数名第一次加括号调用不会执行函数代码
而是普通的函数变成了迭代器对象(生成器)返回值
"""
print(index) # <function index at 0x1061cd430>
res = index() # <generator object index at 0x10626e660>
print(res)
"""
yield可以在函数体代码中出现多次
每次调用__next__方法都会从上往下执行直到yield代码停留
"""
res.__next__()
res.__next__()
res.__next__()
"""
yield后面如果有数据值,则会像return一样返回出去
如果有多个数据值逗号隔开,那么也会自动组织成元组返回
"""
# 小练习
# 编写生成器 实现range方法的功能
"""简单实现大概功能"""
def my_range(start,end=None,step=1):
if not end:
end = start
start =0
while start< end:
yield start
start +=step
for i in my_range(2,15,2):
print(i)
yield其他用法
def index(name,food=None):
print(f'{name}准备干午饭')
while True:
food = yield
print(f'{name}正在吃{food}')
res = index('jason')
print(res)
res.__next__() # jason准备干午饭
res.__next__() # jason正在吃None
""" send() 方法会自动传值并自动调用__next__方法"""
res.send('韭菜') # jason正在吃韭菜
res.send('生蚝') # jason正在吃生蚝
res.send('腰子') # jason正在吃腰子
生成器表达式
l1 = [i **2 for i in range(10) if i >3]
print(l1) # [16, 25, 36, 49, 64, 81]
l2 = (i **2 for i in range(10) if i >3)
print(l2) # <generator object <genexpr> at 0x105997660>
print(list(l2)) # [16, 25, 36, 49, 64, 81]