python基础21-异常捕获-生成器

今日学习

异常捕获

异常捕获实参演练

异常捕获练习

生成器对象

yield其他用法

生成器表达式

异常捕获

​ 经典疑问?
​ 1.怎么理解异常?
​ 程序在运行的过程中如果出现了异常会导致整个程序的结束?
​ 异常就是程序员口中的‘bug’
​ 2.什么时候需要自己写代码处理异常
​ 当代码不确定什么时候会报错,拿不准的情况下

​ 比如编写网络爬虫访问网址数据并处理,有可能会出现断网数据没有处理不了.

  • 异常的结构

Traceback (most recent call last):
File "D:/pythonProject/day21/02 异常的结构.py", line 13, in <module>
name
NameError: name 'name' is not defined
1.关键字line所在行
	精准提示你哪一行代码出错
2.最后一行冒号左侧
	是错误的类型
3.最后一行冒号右侧
    错误的具体原因(也是改bug的关键)
  • 异常的类型

NameError     	#访问的变量名不存在
IndexError		#索引错误,索引不存在,常为索引超出序列范围
KeyError		#使用了映射中不存在的关键字时引发的关键字错误
SyntaxError		#语法错误
TypeError		#类型错误
  • 异常的分类

切记!!

1.语法错误	
	不允许出现的,一旦出现请立即修改!!
2.逻辑错误
	允许出现,允许出错之后修改即可!!
写代码一定要自己大致的看一下,然后再提交
  • 异常捕获实参演练

  • 异常捕获的使用相当于提前预测可能出现的问题,并提前给处理的措施

  • 基本语法结构()

    try:
        可能会出错的代码(被try监控)
    except 错误类型1 as e:  # e就是具体错误的原因
        对应错误类型1的解决措施
    except 错误类型2 as e:  # e就是具体错误的原因
        对应错误类型2的解决措施
    except 错误类型3 as e:  # e就是具体错误的原因
        对应错误类型3的解决措施
    
  • 万能异常(笼统的处理方式)

    try:
        # name
        # d = {'name':'jason'}
        #d['pwd']
        123 + 'hello'
    except Exception as e:  # 万能异常方式1
        print(e)
    except BaseException as e:  # 万能异常方式2
        print(e)
    ----执行结果---------------
    unsupported operand type(s) for +: 'int' and 'str'
    
  • 异常捕获其他操作补充

4.1.else与finally      #没有异常执行else,finally出现的话,有没有异常最终都要执行。
try:
    name
except Exception as e:
    print('你出错了 你个小垃圾')
else:
    print('try监测的代码没有出错的情况下正常运行结束 则会执行else子代码')
finally:
    print('try监测的代码无论有没有出错 最后都会执行finally子代码')
------执行结果-------------
你出错了 你个小垃圾
try监测的代码无论有没有出错 最后都会执行finally子代码
---------------------------------------------------------------
断言	#assert
   
    	name = 'jason'  # 通过一系列的手段获取来的数据
    	assert isinstance(name, list)  # 断言数据属于什么类型 如果不对则直接报错 对则正常执行下面的代码
    	print('针对name数据使用列表相关的操作')
---------------------------------------------------------------        
主动抛异常 #rais
    	name = input('username>>>:').strip()
		if name == 'jason':
			# raise NameError('jason来了 快跑!!!')
			raise Exception('反正就是不能过')
        else:
			print('不是jason 那没事了')
-------------------------------------------------------------------      
5.强调
	1.异常捕获能尽量少用就尽量少用
	2.被try监测的代码能尽量少就尽量少
  • 异常捕获练习

    #for循环内部的本质
    #需求:使用while+异常捕获实现for循环的功能
    l1 = [11, 22, 33, 44, 55, 66, 77, 88]
    while True:
        try:
            print(res.__next__())
        except Exception as e:
            break
    ----------------------------------------------------------------   
    

生成器对象

  • 1.什么是生成器对象?

    ​ 本质是迭代器对象,只不过迭代器是解释器提供我们的(现成的)

    ​ 生成器是我们自己定义出来的(自己动手,丰衣足食)

    ​ 双下iter 和双下next

  • 2,我们学生成器的目的是什么?

    ​ 为了优化代码

    ​ 一种不依赖于索引取值的通用方式

    ​ 可以节省数据类型的内存占用空间()

  • 3.生成器对象代码实现

def index():
    print('我是谁呀 嘿嘿嘿~')
    yield 111, 222, 333
    print('你追我 如果你追到我 我就... 嘿嘿嘿~')
    yield 222
    print('实在跑不动了 嘿嘿嘿~')
    yield 333
print(index)
print(res)  


res = index()
res.__next__()     #yield可以在函数代码中
res.__next__()
res.__next__()
print(res.__next__())
--------------执行结果--------------
<function index at 0x0000018C9E738280>
<generator object index at 0x000001B754CAAC10>
我是谁呀 嘿嘿嘿~
你追我 如果你追到我 我就... 嘿嘿嘿~
实在跑不动了 嘿嘿嘿~
------------------------------------
 解释
-----------------------------      -
"""
当函数体代码中有yield关键字
那么函数名第一次加括号调用不会执行函数体代码
而是由普通的函数变成了迭代器对象(生成器)  返回值
"""
yield可以在函数体代码中出现多次
每次调用__next__方法都会从上往下执行直到遇到yield代码停留在此处
 还是同样的例子
 def index():
    print('我是谁呀 嘿嘿嘿~')
    yield 111, 222, 333            
    print('你追我 如果你追到我 我就... 嘿嘿嘿~')
    yield 222
    print('实在跑不动了 嘿嘿嘿~')
    yield 333
print(index)
print(res)  
print(res.__next__())
#print(res.__next__())
# print(res.__next__())
# print(res.__next__())
---------执行结果-------------------
我是谁呀 嘿嘿嘿~
(111, 222, 333)
"""
yield后面如果有数据值 则会像return一样返回出去
如果有多个数据值逗号隔开 那么也会自动组织成元组返回
"""
  • yield其他用法

    def index(name,food=None):
        print(f'{name}准备干午饭!!!')
        while True:
            food = yield
            print(f'{name}正在吃{food}')
    res = index('jason')
    res.__next__()
    res.send('生蚝')  # 传值并自动调用__next__方法
    res.send('韭菜')  # 传值并自动调用__next__方法
    res.send('腰子')  # 传值并自动调用__next__方法
    -----------执行结果-------------
    jason准备干午饭!!!
    jason正在吃生蚝
    jason正在吃韭菜
    jason正在吃腰子
    

生成器表达式

# l1 = [i**2 for i in range(10) if i > 3]
# print(l1)
# l1 = (i**2 for i in range(10) if i > 3)
# print(l1)  
-----------------执行结果------------------------
[16, 25, 36, 49, 64, 81]
<generator object <genexpr> at 0x000001C7566F6900>
---------------解释---------------------------
相比列表表达式,将[]换成了(),返回对象不是一个列表,而是一个生成器,相比列表更加省内存
(返回值 for 元素 in 可迭代对象 if 条件)
posted @ 2022-07-12 19:33  名字长的像一只老山羊  阅读(44)  评论(0编辑  收藏  举报