博客
关于我
python基础之--迭代器和生成器及异常处理
阅读量:801 次
发布时间:2023-03-07

本文共 4498 字,大约阅读时间需要 14 分钟。

迭代器与生成器及异常处理

一、迭代器

迭代器是一种对象,实现了Python的迭代协议(__iter__() 和 __next__() 方法)。通过迭代器,可以逐个访问容器中的元素。

1.1 迭代器的特点

  • 惰性计算:按需生成数据,节省内存。
  • 实现协议:
    • __iter__():返回自身。
    • __next__():返回下一个元素;如果没有更多元素,则抛出 StopIteration 异常。
  • **可迭代对象(Iterable)**与迭代器不同:
    • 可迭代对象实现 __iter__() 方法,返回一个迭代器。
    • 迭代器既实现 __iter__() 又实现 __next__()。

1.2 创建迭代器

代码如下(示例):

arr = [1, 2, 3, 4, 5]
iterator = iter(arr)
# 通过多次调用 next() 获取元素
re = next(iterator)
print(re) # 输出: 1
re = next(iterator)
print(re) # 输出: 2
# 迭代器用完后再次调用 next() 会抛出 StopIteration
# try:
# re = next(iterator)
# except StopIteration:
# print("迭代器用完")
12345

1.3 自定义迭代器

代码如下:

class Box:
def __init__(self, width):
self.width = width
def __iter__(self):
return self
def __next__(self):
if self.width > 0:
self.width -= 1
return self.width
else:
raise StopIteration
b1 = Box(6)
for i in b1:
print(i)
6 5 4 3 2 1

1.4 案例

代码如下:

import math
class myData:
def __init__(self, data, batch_size=10):
self.data = data
self.index = -1
self.batch_size = batch_size
def __iter__(self):
return self
def __next__(self):
self.index += 1
if self.index >= math.ceil(len(self.data) / self.batch_size):
raise StopIteration
return self.data[self.index * self.batch_size : self.index * self.batch_size + self.batch_size]
data = myData(
["a", "b", "c", "d", "asd", "asd", "asdf", "12as", "asasd",
"a", "b", "c", "d", "asd", "asd", "asdf", "12as", "asasd"],
batch_size=4
)
data_loader = iter(data)
# 获取前几批数据
re = next(data_loader)
print(re) # 输出: ['a', 'b', 'c', 'd']
re = next(data_loader)
print(re) # 输出: ['asd', 'asd', 'asdf', '12as']
re = next(data_loader)
print(re) # 输出: ['asasda', 'b', 'c', 'd']
re = next(data_loader)
print(re) # 输出: ['asd', 'asd', 'asdf', '12as']
re = next(data_loader)
print(re) # 输出: 'asasd'
['a', 'b', 'c', 'd']['asd', 'asd', 'asdf', '12as']['asasda', 'b', 'c', 'd']['asd', 'asd', 'asdf', '12as']['asasd']

二、生成器

生成器是一种特殊的迭代器,通过函数定义,用 yield 关键字生成值。生成器可以自动实现迭代协议,无需手动实现 __iter__() 和 __next__() 方法。

2.1 生成器的特点

  • 简洁:比手动实现迭代器更易写。
  • 惰性计算:每次调用 next() 时生成一个值。
  • yield:暂停函数执行并返回值,保留函数的状态。

代码如下:

def fn():
print("111")
yield "10000"
print("222")
yield "20000"
re = fn()
print(1) # 输出: 1
print(next(re), "=============") # 输出: 10000 =============
print(2) # 输出: 2
print(next(re)) # 输出: 20000 =============
print(3) # 输出: 3
11110000 =============2222200003

2.2 生成器表达式

代码如下:

def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield b
a, b = b, a + b
fib_gen = fibonacci(10)
for num in fib_gen:
print(num)
11235813213455

2.3 迭代器与生成器的区别对比

特性 迭代器 生成器
实现 手动实现类方法 使用函数和 yield 定义
代码简洁性 较复杂 简单
状态管理 手动管理 自动保存
惰性计算 支持 支持
示例应用 复杂迭代逻辑 简单数据流生成

三,异常处理

程序可能出错时,后面的代码不执行。为了让程序继续执行,可以使用异常处理语法。异常处理可以让程序在出错后继续执行后面的代码,增强程序的健壮性。

3.1 try 语句

  • 作用:捕获异常,通知程序,恢复正常状态。
  • 说明:
    • except 子句可以有 1 个或多个错误类型匹配。
    • else 子句在没有错误发生时执行。
    • finally 子句在任何情况下都执行。

代码如下:

try:
arr = [100, 20]
x = arr[100] # 出错
print(x)
except IndexError:
print("数组越界")
except ValueError:
print("数据类型错误")
else:
print("没有异常")
finally:
print("不管有没有异常,都会执行")
# 输出:
# 数组越界
# 不管有没有异常,都会执行

3.2 raise 语句

  • 作用:主动抛出错误。
  • 示例:
def fn():
x = 10
if 5 < x:
print(x)
else:
raise ValueError("x的值不在范围内")
try:
fn()
except ValueError as e:
print(e)
print("后续代码")

3.3 常见错误类型

以下是几种常见的错误类型及其说明:

错误类型 说明
ZeroDivisionError 除法或取模运算中除以零
ValueError 传入无效的参数
AssertionError 断言语句失败
StopIteration 迭代器没有更多值
IndexError 序列中没有对应的索引
IndentationError 缩进错误
OSError 输入/输出操作失败
ImportError 导入模块失败
NameError 未声明/初始化对象
AttributeError 对象没有属性
GeneratorExit 生成器(generator) 被异常退出
TypeError 对类型无效的操作
KeyboardInterrupt 用户中断执行(通常是输入^C)
OverflowError 数值运算超出最大限制
FloatingPointError 浮点计算错误
BaseException 所有异常的基类
SystemExit 解释器请求退出
Exception 常规错误的基类
StandardError 所有内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
EOFError 到达输入末尾(EOF)
EnvironmentError 操作系统错误的基类
WindowsError 系统调用失败
LookupError 无效数据查询的基类
KeyError 映射中没有对应的键
MemoryError 内存溢出错误
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference) 访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError 语法错误
TabError 代码中混合了 tab 和 空格
SystemError 一般解释器系统错误
UnicodeError Unicode 相关错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误

3.4 案例

def get_age():
age = int(input("请输入年龄:"))
if age > 140 or age < 1:
raise ValueError("年龄超出范围!")
else:
print("年龄:", age)
get_age()
ValueError: 年龄超出范围!

转载地址:http://ooofk.baihongyu.com/

你可能感兴趣的文章
Python和RF编写web自动化
查看>>
python和js哪个难_【Python】记一次学习,Python 与 js 在实现闭包时的差异
查看>>
python和java哪个更值得学——来自知乎高赞回答
查看>>
python和c混合编程 github_在pycharm中使用git版本管理以及同步github的方法
查看>>
python命名空间更改_Python模块xml.etree.ElementTree自动修改xml命名空间键
查看>>
Python命名中尾随下划线有什么好处?
查看>>
Python启动脚本
查看>>
Python听写汇总结果
查看>>
python吊打Excel?屁!那是你不会用!
查看>>
Python合并两张图片 | 先叠透明度再合并 (附Demo)
查看>>
python各进制的表述与转换
查看>>
python各种库安装
查看>>
python可视化matplotlib_如何使用Python中最强大的可视化工具Matplotlib?
查看>>
python可维护性_使用这7大神器,让你的Python 代码更容易于维护
查看>>
Python只运行一次while循环
查看>>
python变量的详细教程_Python零基础入门教程之语法入门[变量](第二期)
查看>>
Python变量命名方法-ChatGPT4o作答
查看>>
Python变量与运算符
查看>>
Python变量/运算符/函数/模块/string
查看>>
python发送邮件的时候出现 error (535, b‘5.7.3 Authentication unsuccessful‘) 解决方法
查看>>