python学习笔记

今日内容概要

  • 异常捕获
  • 生成器对象
  • 生成器表达式

今日内容详细

异常捕获

1.如何理解异常

程序在运行的过程中如果出现了异常会导致整个程序的结束

异常就是程序员口中的'bug'

异常捕获的目的:为了增强程序的健壮性,即便程序运行过程中出错,也不

要终止程序,而是捕获异常并处理

2.异常的结构

1.关键字line所在行

精准提示你在哪一行代码出错

2.最后一行冒号左侧

是错误的类型

3.最后一行冒号右侧

错误的具体原因(也是改bug的关键)

3.常见异常的类型

1.NameError:试图访问的变量名不存在

2.IndexError:索引错误,使用的索引不存在,常为索引超出序列范围

3.KeyError:使用了映射中不存在的关键字(键)时引发的关键字错误

4.SyntaxError:语法错误

5.TypeError:类型错误

4.异常的分类

1.语法错误

不允许出现的,一旦出现请立刻修改

2.逻辑错误

允许出现的,允许出错之后修改即可

异常捕获实操演练

1.什么时候才可能会需要自己写代码处理异常

当代码不确定什么时候会报错的情况下

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

3.异常捕获的代码实现

1.基本语法结构(针对性很强)

try:
    可能会出错的代码(被try监控)
except 错误类型1 as e:  # e就是具体错误的原因
    对应错误类型1的解决措施
except 错误类型2 as e:  # e就是具体错误的原因
    对应错误类型2的解决措施
except 错误类型3 as e:  # e就是具体错误的原因
    对应错误类型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.异常捕获其他操作补充

1.else与finally

try:
    name
except Exception as e:
    print('try监测的代码出错的情况下执行此代码')
else:
    print('try监测的代码没有出错的情况下正常运行结束 则会执行else子代码')
finally:
    print('try监测的代码无论有没有出错 最后都会执行finally子代码')

2.断言

name = 'jason'  # 通过一系列的手段获取来的数据
assert isinstance(name, list)  # 断言数据属于什么类型 如果不对则直接报错 对则正常执行下面的代码
print('针对name数据使用列表相关的操作')

3.主动抛异常

name = input('username:').strip()
if name == 'jason':
    raise Exception('主动报错')
elseprint('不是jason')

5.强调

1.异常捕获能尽量少用就尽量少用

2.被try检测的代码能尽量少就尽量少

异常捕获使用try检测代码,很占内存空间,所以尽量少用

6.异常捕获练习

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
    print('第二次执行')
    yield 222
    print('第三次执行')
    yield 333
"""
当函数体代码中有yield关键字
那么函数名第一次加括号调用不会执行函数体代码
而是由普通的函数变成了迭代器对象(生成器)  返回值
"""
print(index)  # <function index at 0x000001F499F7A5E0>
res = index()
print(res)  # <generator object index at 0x0000021E18BACA50>
res.__next__()
res.__next__()
res.__next__()
"""
yield可以在函数体代码中出现多次
每次调用__next__方法都会从上往下执行直到遇到yield代码停留在此处
"""
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
"""
yield后面如果有数据值 则会像return一样返回出去
如果有多个数据值逗号隔开 那么也会自动组织成元组返回
"""

4.yield关键字其他用法

  1. 在函数体代码中出现, 可以将函数变成生成器.
  2. 在执行过程中, 可以将后面的值返回去, 类似于return.
  3. 可以暂停住代码的运行
  4. 还可以接受外界的传值(了解)
def index(name,food=None):
    print(f'{name}准备干午饭!!!')
    while True:
        food = yield
        print(f'{name}正在吃{food}')
res = index('jason')
res.__next__()
res.send('生蚝')  #  send 传值并自动调用__next__方法
res.send('韭菜')  # 传值并自动调用__next__方法
res.send('腰子')  # 传值并自动调用__next__方法

生成器表达式

相比列表表达式,将[]换成了(),返回对象不是一个列表,而是一个生成器,相比列表更加省内存
(返回值 for 元素 in 可迭代对象 if 条件)
l1 = (i**2 for i in range(10) if i > 3)
print(l1)  # <generator object <genexpr> at 0x000001A793439C10>
posted @   空白o  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示