异常与生成器

异常处理和生成器对象

  • 异常语法结构

  • 异常处理实战

  • 生成器对象

  • 生成器实现range方法

  • 生成器表达式

  • 生成器笔试题

  • 异常简介
    异常的分类:

  1. 语法错误
  2. 逻辑错误
    异常结构
  3. 定位信息
  4. 错误类型
  5. 错误信息
  • 异常常见错误类型
1. SyntexError
2. NameError
3. IndexError
4. KeyError
5. IndetationError
  • 异常语法结构
try:
	待监测的代码
	except 错误类型
	正对上述错误类型指定的方案
  1. 针对不同的错误类型指定不同的方案
try:
	待监测的代码
	except 错误类型1 as e:  # e 就是报的错误类型
		错误方案1
	except 错误类型2 as e:
		错误方案2
	except 错误类型3 as e:
		错误方案3
  1. 万能异常Exception/BaseException
# 万能异常
try:
	待监测代码
	except Exception as e:
		常见报错都都会执行此方案

# 结合else使用
try:
	待监测代码
	except Exception as e:
		错误执行方案
else:  # 在上面的代码正常执行没有执行异常方案时执行else
	print('哈哈哈,上面没有异常')


# 结合finally
try:
	待监测代码
	except Exception as e:
		异常解决方案
else:
	print('上面正常执行没有错误我就执行')
finally:
	print('上面的先上,无聊他们如何我都执行')

  1. 断言

断言:预测上面出现的错误类型,并确定错误异常类型

name = 'wesley'
assert isinstance(name, str)
print('类型为字符串')
#  如果类型判断错误就报错
  1. 主动抛出异常
name = 'andy'
if name == 'andy':
	raise Exception('又是你,老子不干了')
else:
	print('哈哈哈不是andy,继续运行')

  • 使用异常处理的注意事项
  1. 异常处理能尽量少用就少用
  2. 被try监测的代码能尽量少就尽量少
  3. 当代码中可能会出现一些无法控制的情况报错才应该考虑使用
  • 使用异常 ,whlie循环,迭代器对象实现for循环
# 异常联系,使用while循环,异常,迭代器对象完成for循环功能

l1 = [11, 22, 33, 44, 55, 66, 77, 88, 99]
new = l1.__iter__()
while True:
    try:
        print(new.__next__())
    except StopIteration:
        break
  • 生成器对象
  1. 生成器的本质:具有__iter__和__next__的迭代器对象
  2. 区别在于,迭代器是解释器提供的,生成器是程序员自己手写的
  1. 解释器提供
    数据类型/文件对象>迭代器对象
  2. 程序员提供
    代码,关键字>生成器对象
  • 生成器语法

创建生成器就是在函数体代码中写上关键字yield

# 生成器对象
def my_iter()
	print('这是一个生成器对象')
	yield
# 函数体中如果有yield,第一次调用不会执行,会先生成一个生成器对象(迭代器对象)

res = my_iter()
# 加上括号后调用__next__才会执行函数体代码,并停留yield

res.__next__()
# 每次执行后都回停留在yield,等待下一个yidld




# yield也可以当做返回值使用
def my_iter():
    print('我是第一')
    yield 1
    print('我是第二')
    yield 2
    print('我是第三')
    yield 3

res = my_iter()
r1 = res.__next__()
print(r1)
r2 = res.__next__()
print(r2)
r3 = res.__next__()
print(r3)

  • 使用生成器写reang()函数
# 先写两个参数的
def my_range(start_num, end_num=None):
    if not end_num:
        end_num = start_num
        start_num = 0
    while start_num < end_num:
        yield start_num
        start_num = start_num + 1

for i in my_range(10, 20):
    print(i)
    
# 三个参数
def my_range(start_num, end_num=None, step=1):
    if not end_num:
        end_num = start_num
        start_num = 0
    if step == 1:
        while start_num < end_num:
            yield start_num
            start_num + 1
    elif step != 1:
        while start_num < end_num:
            yield start_num
            start_num += step


for i in my_range(2, 100, 10):
    print(i)
# 再来看看这个my_reang如何支持负数
def my_range(start_num, end_num=None, step=1):
    if not end_num:
        end_num = start_num
        start_num = 0
    if step == 1:
        while start_num < end_num:
            yield start_num
            start_num + 1
    elif step > 1:
        while start_num < end_num:
            yield start_num
            start_num += step
    elif step < 0:
        num = abs(step)
        while start_num < end_num:
            yield end_num
            end_num -= num

for i in my_range(2, 100, -5):
    print(i)
  • yield 冷门用法
def eat(name, food=None):
    print(f'{name}准备用餐')
    while True:
        food = yield
        print(f'{name}正在吃{food}')
res = eat('wesley')
res.__next__()
res.send('汉堡')
res.send('牛肉干')
#  send的作用是将括号中的值传给yield的变量名再自动调用__next__

  • 生成器表达式

简化代码写法

l1 = (i ** 2 for i in range(10))
print(l1)  # <generator object <genexpr> at 0x100eff660>
res = l1.__iter__()
for i in res:
    print(i)
  • 面试题
def add(n, i):  # 普通函数 返回两个数的和  求和函数
    return n + i
def test():  # 生成器
    for i in range(4):
        yield i
g = test()  # 激活生成器

for n in [1, 10]:
    g = (add(n, i) for i in g)
    """
    第一次for循环
        g = (add(n, i) for i in g)
    第二次for循环
        g = (add(10, i) for i in (add(10, i) for i in g))
    """
print(list(g))
[20, 21, 22, 23]
posted @ 2025-03-13 13:54  樵夫-  阅读(10)  评论(0)    收藏  举报