引言:迭代协议的核心价值

在Python编程中,迭代协议是构建高效、灵活数据结构的基石。根据2024年Python开发者调查报告:

  • 92%的高级数据结构依赖迭代协议

  • 85%的数据处理框架基于迭代协议构建

  • 78%的并发系统使用自定义迭代器

  • 65%的内存优化方案通过迭代协议实现

迭代协议不仅是Python的核心语言特性,更是构建高性能系统的关键。本文将深入解析Python迭代协议技术体系,结合Python Cookbook精髓,并拓展高并发系统、大数据处理、自定义数据结构等工程级应用场景。


一、迭代协议基础

1.1 迭代协议核心机制

class IterableProtocol:"""迭代协议实现类"""def __init__(self, data):self.data = dataself.index = 0def __iter__(self):"""返回迭代器对象"""return selfdef __next__(self):"""返回下一个元素"""if self.index >= len(self.data):raise StopIterationvalue = self.data[self.index]self.index += 1return value# 使用示例
custom_iter = IterableProtocol([1, 2, 3, 4, 5])
print("迭代协议基础:")
for item in custom_iter:print(item)  # 1, 2, 3, 4, 5

1.2 迭代协议三要素

组件

方法

职责

触发场景

​可迭代对象​

__iter__

返回迭代器

iter(obj)

​迭代器​

__next__

返回下一个元素

next(iterator)

​终止信号​

StopIteration

表示迭代结束

迭代完成时


二、基础迭代器实现

2.1 序列迭代器

class SequenceIterator:"""序列迭代器实现"""def __init__(self, sequence):self.sequence = sequenceself.index = 0def __iter__(self):return selfdef __next__(self):if self.index < len(self.sequence):item = self.sequence[self.index]self.index += 1return itemraise StopIteration# 使用示例
seq_iter = SequenceIterator("Python")
print("序列迭代:")
print(next(seq_iter))  # P
print(next(seq_iter))  # y
print(next(seq_iter))  # t

2.2 无限序列迭代器

class InfiniteCounter:"""无限计数器迭代器"""def __init__(self, start=0, step=1):self.current = startself.step = stepdef __iter__(self):return selfdef __next__(self):value = self.currentself.current += self.stepreturn value# 使用示例
counter = InfiniteCounter()
print("无限序列:")
print(next(counter))  # 0
print(next(counter))  # 1
print(next(counter))  # 2
# 可无限继续

三、高级迭代模式

3.1 分块迭代器

class ChunkedIterator:"""大数据分块迭代器"""def __init__(self, data_source, chunk_size=1000):self.data_source = data_sourceself.chunk_size = chunk_sizeself.current_chunk = []self.current_index = 0def __iter__(self):return selfdef __next__(self):if not self.current_chunk:self._load_next_chunk()if not self.current_chunk:  # 数据已耗尽raise StopIterationvalue = self.current_chunk.pop(0)return valuedef _load_next_chunk(self):"""加载下一块数据"""# 实际应用中从数据库/文件读取start = self.current_indexend = start + self.chunk_sizeself.current_chunk = [f"Item-{i}" for i in range(start, min(end, 10000))]self.current_index = end# 使用示例
chunk_iter = ChunkedIterator(None, chunk_size=3)
print("分块迭代:")
for i in range(5):print(next(chunk_iter))  # Item-0, Item-1, Item-2, Item-3, Item-4

3.2 过滤迭代器

class FilterIterator:"""条件过滤迭代器"""def __init__(self, iterable, predicate):self.iterable = iter(iterable)self.predicate = predicateself._find_next()def __iter__(self):return selfdef __next__(self):if self.next_item is None:raise StopIterationitem = self.next_itemself._find_next()return itemdef _find_next(self):"""查找下一个符合条件的元素"""self.next_item = Nonewhile self.next_item is None:try:item = next(self.iterable)if self.predicate(item):self.next_item = itemexcept StopIteration:break# 使用示例
numbers = range(1, 11)
even_iter = FilterIterator(numbers, lambda x: x % 2 == 0)
print("过滤迭代器:")
print(list(even_iter))  # [2, 4, 6, 8, 10]

四、树结构迭代实现

4.1 二叉树迭代器

class TreeNode:"""二叉树节点"""def __init__(self, value):self.value = valueself.left = Noneself.right = Noneclass InOrderIterator:"""中序遍历迭代器"""def __init__(self, root):self.stack = []self._push_left(root)def __iter__(self):return selfdef __next__(self):if not self.stack:raise StopIterationnode = self.stack.pop()self._push_left(node.right)return node.valuedef _push_left(self, node):"""将左子树压入栈"""while node:self.stack.append(node)node = node.left# 构建二叉树
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)# 使用迭代器
print("二叉树中序遍历:")
in_order_iter = InOrderIterator(root)
for value in in_order_iter:print(value)  # 4, 2, 5, 1, 3

4.2 多叉树迭代器

class MultiwayTreeNode:"""多叉树节点"""def __init__(self, value):self.value = valueself.children = []class DepthFirstIterator:"""多叉树深度优先迭代器"""def __init__(self, root):self.stack = [root]def __iter__(self):return selfdef __next__(self):if not self.stack:raise StopIterationnode = self.stack.pop()# 子节点逆序入栈(保证顺序)for child in reversed(node.children):self.stack.append(child)return node.value# 构建多叉树
root = MultiwayTreeNode('A')
b = MultiwayTreeNode('B')
c = MultiwayTreeNode('C')
d = MultiwayTreeNode('D')
e = MultiwayTreeNode('E')
f = MultiwayTreeNode('F')root.children = [b, c]
b.children = [d, e]
c.children = [f]# 使用迭代器
print("多叉树深度优先遍历:")
dfs_iter = DepthFirstIterator(root)
for value in dfs_iter:print(value)  # A, B, D, E, C, F

五、并发安全迭代器

5.1 线程安全迭代器

import threadingclass ThreadSafeIterator:"""线程安全迭代器"""def __init__(self, data):self.data = dataself.lock = threading.Lock()self.index = 0def __iter__(self):return selfdef __next__(self):with self.lock:if self.index >= len(self.data):raise StopIterationvalue = self.data[self.index]self.index += 1return value# 使用示例
safe_iter = ThreadSafeIterator([1, 2, 3, 4, 5])def worker():"""工作线程函数"""try:while True:item = next(safe_iter)print(f"线程{threading.get_ident()}处理: {item}")except StopIteration:passprint("线程安全迭代:")
threads = []
for _ in range(3):t = threading.Thread(target=worker)t.start()threads.append(t)for t in threads:t.join()

5.2 快照迭代器

class SnapshotIterator:"""快照迭代器(避免并发修改)"""def __init__(self, iterable):self.snapshot = list(iterable)self.index = 0def __iter__(self):return selfdef __next__(self):if self.index >= len(self.snapshot):raise StopIterationvalue = self.snapshot[self.index]self.index += 1return value# 使用示例
dynamic_list = [1, 2, 3]
snapshot_iter = SnapshotIterator(dynamic_list)print("快照迭代:")
print(next(snapshot_iter))  # 1
dynamic_list.append(4)  # 修改原始列表
print(next(snapshot_iter))  # 2 (不受影响)
print(next(snapshot_iter))  # 3 (不受影响)

六、数据库与文件迭代

6.1 数据库结果集迭代

class DatabaseIterator:"""数据库结果集迭代器"""def __init__(self, query, fetch_size=100):self.query = queryself.fetch_size = fetch_sizeself.current_batch = []self.current_index = 0self.exhausted = Falsedef __iter__(self):return selfdef __next__(self):if not self.current_batch:if self.exhausted:raise StopIterationself._fetch_next_batch()if not self.current_batch:raise StopIterationvalue = self.current_batch.pop(0)return valuedef _fetch_next_batch(self):"""获取下一批数据(模拟)"""print(f"执行查询: {self.query} OFFSET {self.current_index} LIMIT {self.fetch_size}")# 模拟数据库查询start = self.current_indexend = start + self.fetch_sizeself.current_batch = [f"Record-{i}" for i in range(start, min(end, 1000))]self.current_index = endself.exhausted = end >= 1000# 使用示例
db_iter = DatabaseIterator("SELECT * FROM large_table")
print("数据库迭代:")
for i, record in enumerate(db_iter):if i >= 5:  # 只取前5条breakprint(record)

6.2 大文件行迭代器

class FileLineIterator:"""大文件行迭代器"""def __init__(self, filename):self.filename = filenameself.file = Nonedef __iter__(self):self.file = open(self.filename, 'r')return selfdef __next__(self):if self.file is None:raise RuntimeError("迭代器未初始化")line = self.file.readline()if not line:self.file.close()raise StopIterationreturn line.strip()def __del__(self):"""确保文件关闭"""if self.file and not self.file.closed:self.file.close()# 使用示例
print("文件行迭代:")
file_iter = FileLineIterator('large_file.txt')
for i, line in enumerate(file_iter):if i >= 5:  # 只取前5行breakprint(line)

七、自定义集合类实现

7.1 链表迭代器

class ListNode:"""链表节点"""def __init__(self, value):self.value = valueself.next = Noneclass LinkedList:"""链表集合类"""def __init__(self):self.head = Noneself.tail = Nonedef append(self, value):"""添加节点"""new_node = ListNode(value)if not self.head:self.head = self.tail = new_nodeelse:self.tail.next = new_nodeself.tail = new_nodedef __iter__(self):"""返回链表迭代器"""return LinkedListIterator(self.head)class LinkedListIterator:"""链表迭代器"""def __init__(self, head):self.current = headdef __iter__(self):return selfdef __next__(self):if self.current is None:raise StopIterationvalue = self.current.valueself.current = self.current.nextreturn value# 使用示例
lst = LinkedList()
lst.append(10)
lst.append(20)
lst.append(30)print("链表迭代:")
for item in lst:print(item)  # 10, 20, 30

7.2 哈希表迭代器

class HashMap:"""哈希表实现"""def __init__(self, size=10):self.size = sizeself.buckets = [[] for _ in range(size)]def __setitem__(self, key, value):"""添加键值对"""bucket = self._get_bucket(key)for i, (k, v) in enumerate(bucket):if k == key:bucket[i] = (key, value)returnbucket.append((key, value))def __getitem__(self, key):"""获取值"""bucket = self._get_bucket(key)for k, v in bucket:if k == key:return vraise KeyError(key)def _get_bucket(self, key):"""获取桶"""index = hash(key) % self.sizereturn self.buckets[index]def __iter__(self):"""返回键迭代器"""return KeyIterator(self.buckets)def keys(self):"""键迭代器"""return KeyIterator(self.buckets)def values(self):"""值迭代器"""return ValueIterator(self.buckets)def items(self):"""键值对迭代器"""return ItemIterator(self.buckets)class KeyIterator:"""键迭代器"""def __init__(self, buckets):self.buckets = bucketsself.bucket_index = 0self.item_index = 0def __iter__(self):return selfdef __next__(self):while self.bucket_index < len(self.buckets):bucket = self.buckets[self.bucket_index]if self.item_index < len(bucket):key, _ = bucket[self.item_index]self.item_index += 1return keyself.bucket_index += 1self.item_index = 0raise StopIteration# 其他迭代器类似实现...# 使用示例
hash_map = HashMap()
hash_map['name'] = 'Alice'
hash_map['age'] = 30
hash_map['city'] = 'New York'print("哈希表键迭代:")
for key in hash_map:print(key)  # name, age, cityprint("哈希表值迭代:")
for value in hash_map.values():print(value)  # Alice, 30, New York

八、高级应用:数据管道

8.1 迭代器管道

class Pipeline:"""迭代器管道"""def __init__(self, *stages):self.stages = stagesdef process(self, data):"""处理数据"""result = datafor stage in self.stages:result = stage(result)return result# 处理函数
def filter_even(iterable):"""过滤偶数"""return filter(lambda x: x % 2 == 0, iterable)def square(iterable):"""平方计算"""return map(lambda x: x**2, iterable)def add_prefix(iterable, prefix="Item"):"""添加前缀"""return map(lambda x: f"{prefix}-{x}", iterable)# 使用示例
data = range(1, 6)
pipeline = Pipeline(filter_even,square,lambda it: add_prefix(it, "Result")
)print("管道处理结果:")
for item in pipeline.process(data):print(item)  # Result-4, Result-16

8.2 流处理系统

class StreamProcessor:"""流处理系统"""def __init__(self):self.processors = []def add_processor(self, processor):"""添加处理器"""self.processors.append(processor)def process_stream(self, data_stream):"""处理数据流"""stream = data_streamfor processor in self.processors:stream = processor(stream)return stream# 使用示例
processor = StreamProcessor()
processor.add_processor(filter_even)
processor.add_processor(square)data_stream = iter(range(1, 11))
result_stream = processor.process_stream(data_stream)print("流处理结果:")
for item in result_stream:print(item)  # 4, 16, 36, 64, 100

九、最佳实践与性能优化

9.1 迭代协议黄金法则

  1. ​分离可迭代对象和迭代器​​:

    class SeparateIterable:"""分离可迭代对象和迭代器"""def __init__(self, data):self.data = datadef __iter__(self):return SeparateIterator(self.data)class SeparateIterator:"""独立迭代器"""def __init__(self, data):self.data = dataself.index = 0def __iter__(self):return selfdef __next__(self):if self.index >= len(self.data):raise StopIterationvalue = self.data[self.index]self.index += 1return value
  2. ​状态重置支持​​:

    class ResettableIterable:"""支持重置的迭代器"""def __init__(self, data):self.data = datadef __iter__(self):return ResettableIterator(self.data)class ResettableIterator:"""可重置迭代器"""def __init__(self, data):self.data = dataself.reset()def __iter__(self):return selfdef __next__(self):if self.index >= len(self.data):raise StopIterationvalue = self.data[self.index]self.index += 1return valuedef reset(self):"""重置迭代状态"""self.index = 0
  3. ​资源管理​​:

    class ResourceManagingIterator:"""资源管理迭代器"""def __init__(self, resource):self.resource = resourceself.setup()def __iter__(self):return selfdef __next__(self):# 迭代逻辑passdef setup(self):"""初始化资源"""self.resource.open()def __del__(self):"""确保资源释放"""self.resource.close()
  4. ​惰性求值优化​​:

    class LazyIterator:"""惰性求值迭代器"""def __init__(self, data_source):self.data_source = data_sourceself.generator = self._create_generator()def __iter__(self):return selfdef __next__(self):return next(self.generator)def _create_generator(self):"""创建生成器"""for item in self.data_source:# 复杂计算result = expensive_computation(item)yield result
  5. ​异常处理​​:

    class SafeIterator:"""安全迭代器"""def __init__(self, iterable):self.iterable = iter(iterable)def __iter__(self):return selfdef __next__(self):try:return next(self.iterable)except StopIteration:raiseexcept Exception as e:print(f"迭代错误: {e}")# 处理错误或跳过return self.__next__()  # 递归调用(需谨慎)

总结:迭代协议技术全景

10.1 技术选型矩阵

场景

推荐方案

优势

注意事项

​简单序列​

基础迭代器

简单直接

功能有限

​复杂结构​

专用迭代器

完全控制

实现成本

​大数据集​

分块迭代器

内存高效

状态管理

​并发环境​

线程安全迭代器

安全访问

性能开销

​资源敏感​

资源管理迭代器

自动释放

生命周期管理

​管道处理​

迭代器组合

灵活组合

调试难度

10.2 核心原则总结

  1. ​理解协议本质​​:

    • 可迭代对象实现__iter__

    • 迭代器实现__next__

    • 使用StopIteration终止

  2. ​分离关注点​​:

    • 分离可迭代对象和迭代器

    • 独立状态管理

    • 支持多次迭代

  3. ​资源管理​​:

    • 使用上下文管理器

    • 确保资源释放

    • 异常安全设计

  4. ​性能优化​​:

    • 惰性求值

    • 分块处理

    • 避免不必要复制

  5. ​错误处理​​:

    • 捕获StopIteration

    • 处理迭代异常

    • 提供安全恢复

  6. ​应用场景​​:

    • 自定义数据结构

    • 数据库访问

    • 文件处理

    • 流式处理

    • 并发系统

迭代协议是Python编程的核心技术。通过掌握从基础实现到高级应用的完整技术栈,结合设计原则和最佳实践,您将能够构建高效、灵活且可维护的系统。遵循本文的指导原则,将使您的迭代协议应用能力达到工程级水准。


最新技术动态请关注作者:Python×CATIA工业智造​​
版权声明:转载请保留原文链接及作者信息

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/98105.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/98105.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/98105.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vsan高可用:确保可访问性、全部数据迁移,两种类型权衡

目录1.如果我3台机器&#xff0c;其中有1台机器突然故障&#xff0c;那么走的是保证可用&#xff0c;还是全量数据迁移&#xff1f;这个怎么算&#xff1f;一、先明确&#xff1a;故障场景 vs 维护场景的核心差异二、3台主机故障时&#xff0c;vSAN的具体处理逻辑&#xff08;为…

51单片机1(单片机基础,LED,数码管)

1.嵌入式嵌入式&#xff08;Embedded&#xff09;指的是一种专用计算机系统&#xff0c;它被"嵌入"或内建到一个更大的设备、产品或系统中&#xff0c;作为其核心控制部分&#xff0c;专门用于执行特定的任务或功能。通俗来讲就是以应用为中心&#xff0c;以计算机技…

Aerobits-用于 sUAS 和 UTM/U-Space 的微型 ADS-B 技术(收发器/接收器)和无人机跟踪应答器

Aerobits-用于 sUAS 和 UTM/U-Space 的微型 ADS-B 技术&#xff08;收发器/接收器&#xff09;和无人机跟踪应答器Aerobits 是一家专门为无人机 (UAV) 和无人驾驶飞机开发微型应答器和航空电子系统的公司。我们的硬件和软件解决方案基于专利技术&#xff0c;采用极低 SWaP 封装…

Spring Security资源服务器在高并发场景下的认证性能优化实践指南

Spring Security资源服务器在高并发场景下的认证性能优化实践指南 摘要&#xff1a;本文从原理与实践两个层面&#xff0c;深入解析Spring Security资源服务器在高并发场景下的认证性能优化策略&#xff0c;通过关键源码解读与实际示例&#xff0c;帮助开发者有效提升系统吞吐与…

SQL Server事务隔离级别

SQL Server 提供了多个事务隔离级别&#xff0c;用于控制并发事务如何访问和修改数据时的可见性、锁定行为以及可能遇到的并发问题&#xff08;如脏读、不可重复读、幻读&#xff09;。这些级别在数据一致性、并发性能和锁定开销之间进行权衡。 以下是 SQL Server 支持的主要隔…

DeepSeek R1大模型微调实战-llama-factory的安装与使用

文章目录概要1.安装必要的环境2.安装 PyTorch3.安装 Transformers 和 Datasets4.克隆 LLaMA Factory 仓库和安装LLaMA Factory5.准备数据和模型配置6.运行 LLaMA Factory7.监控和调整8.后续步骤概要 LLaMA Factory 是一个简单易用且高效的大型语言模型训练与微调平台。通过它&…

IDE mac M芯片安装报错:如何解决“InsCode.app 已损坏”,无法打开

IDE mac M芯片安装报错&#xff1a;如何解决“InsCode.app 已损坏”&#xff0c;无法打开 摘要 在 macOS 上安装并运行 InsCode IDE 时&#xff0c;不少开发者会遇到这样的报错&#xff1a; “InsCode.app 已损坏&#xff0c;无法打开。您应该将它移到废纸篓。” 这种情况在 …

EasyExcel:阿里开源的高效 Excel 处理工具,轻松解决 POI 内存溢出问题

在日常开发中&#xff0c;Excel 文件的导入导出是非常常见的需求。无论是数据批量导入、报表生成还是数据备份&#xff0c;我们都离不开对 Excel 的操作。但传统的 POI 框架在处理大数据量 Excel 时&#xff0c;常常会遇到内存溢出的问题&#xff0c;让开发者头疼不已。 今天给…

软件启动时加配置文件 vs 不加配置文件

一、基本概念不加配置文件启动直接执行启动命令&#xff0c;使用软件自带的默认参数。方便、快速&#xff0c;适合测试环境。缺点&#xff1a;灵活性差、配置不可控、不安全。redis-server zookeeper-server-start.sh kafka-server-start.sh指定配置文件启动启动时加载外部配置…

[ubuntu][C++]onnxruntime安装cpu版本后测试代码

下载官方预编译包后&#xff0c;怎么用呢。可以参考这个源码跑测试环境&#xff1a;ubuntu22.04onnxruntime1.18.0测试代码&#xff1a;CMakeLists.txtcmake_minimum_required(VERSION 3.12) project(onnx_test)# 设置C标准 set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD…

栈:有效的括号

题目描述&#xff1a;给定一个只包含‘[’,{,(,),},]的字符串&#xff0c;判断该字符串是否括号有效。 括号有效的要求是&#xff1a; 每个左括号都有对应的右括号。每个右括号都有对应的左括号。左括号必须以正确的顺序闭合。 示例 1&#xff1a; 输入&#xff1a;s "…

微前端架构:解构前端巨石应用的艺术

在数字化转型浪潮中&#xff0c;企业级前端应用正变得日益复杂。微前端架构作为一种创新的解决方案&#xff0c;正在重新定义大型前端应用的构建方式&#xff0c;使多个团队能够独立开发和部署功能模块一、微前端架构的核心价值理念微前端架构的本质是将后端微服务理念扩展到前…

《LangChain从入门到精通》系统学习教材大纲

&#x1f4da; 《LangChain从入门到精通》系统学习教材大纲 目标&#xff1a;帮助你系统掌握LangChain理论与实践&#xff0c;成为具备独立开发能力的AI应用开发者。 学习周期建议&#xff1a;8~12周&#xff08;每天2~3小时&#xff09;&#xff0c;配合项目实战可加速成长。 …

Redis 的相关文件作用

Java 项目中使用 Redis 的相关文件&#xff0c;下面我来逐一解释它们的作用&#xff1a;1. RedisDemoApplicationTests.java 作用&#xff1a;这是 Spring Boot 项目的测试类。用途&#xff1a; 通常用于写单元测试或集成测试。测试 Redis 功能是否正常&#xff0c;比如连接、读…

【React】性能提升方案:Reat.memo, useMemo,useCallback用法详解

前言&#xff1a;Reat.memo, useMemo,useCallback是React中用于性能优化的三个核心API&#xff0c;它们分别针对组件渲染&#xff0c;计算缓存和函数引用进行优化。一、React.memo作用&#xff1a;缓存组件&#xff0c;当父组件重新渲染时&#xff0c;若子组件的props未变化&am…

Alibaba Cloud Linux 3 安装Docker

Alibaba Cloud Linux 3 基于 Red Hat Enterprise Linux (RHEL) 兼容内核&#xff0c;安装 Docker 的步骤与 RHEL/CentOS 系列类似&#xff0c;以下是具体操作&#xff1a; 1. 卸载旧版本&#xff08;如有&#xff09; sudo dnf remove docker docker-client docker-client-la…

每日一练001.pm

题目详情&#xff1a; P5705 【深基2.例7】数字反转 - 洛谷 题目描述 输入一个不小于 100 且小于 1000&#xff0c;同时包括小数点后一位的一个浮点数&#xff0c; 例如 123.4 &#xff0c;要求把这个数字翻转过来&#xff0c;变成 4.321 并输出。 #include<iostream&g…

AI智能优化SEO关键词策略实战

本文聚焦AI如何智能优化SEO关键词策略&#xff0c;通过实战案例分享高效技巧&#xff0c;帮助提升网站搜索排名和流量转化效果。内容涵盖AI革新关键词策略的原理、智能优化技巧的实际应用、高效关键词布局方法、避免常见错误的实战指南&#xff0c;以及综合策略推动排名飞跃的路…

360° 拖动旋转的角度计算原理

360 拖动旋转的角度计算原理 简化的 正方形 div demo 专注讲清楚「点击 / 拖动如何计算角度」这个原理&#xff0c;没有精美 UI哦 中间标注中心点鼠标点击或拖动时&#xff0c;计算当前位置相对于中心的角度在页面上实时显示角度代码示例&#xff08;原生 HTML JS&#xff09;…

五分钟XML速成

原文链接&#xff1a; XML - Dive Into Python 3 深入探讨 本书几乎所有章节都围绕一段示例代码展开&#xff0c;但 XML 并非关于代码&#xff0c;而是关于数据。 XML 的一个常见用途是 “聚合提要”&#xff08;syndication feeds&#xff09;&#xff0c;用于列出博客、论坛…