- Preface 前言
- 第1章 引论
- 第2章 编程惯用法
- 第3章 基础语法
- 建议19:有节制地使用 from…import 语句
- 建议20:优先使用 absolute import 来导入模块
- 建议21:i+=1 不等于 ++i
- 建议22:使用 with 自动关闭资源
- 建议23:使用 else 子句简化循环(异常处理)
- 建议24:遵循异常处理的几点基本原则
- 建议25:避免 finally 中可能发生的陷阱
- 建议26:深入理解 None 正确判断对象是否为空
- 建议27:连接字符串应优先使用 join 而不是 +
- 建议28:格式化字符串时尽量使用 .format 方式而不是 %
- 建议29:区别对待可变对象和不可变对象
- 建议30:[]、() 和 {}:一致的容器初始化形式
- 建议31:记住函数传参既不是传值也不是传引用
- 建议32:警惕默认参数潜在的问题
- 建议33:慎用变长参数
- 建议34:深入理解 str() 和 repr() 的区别
- 建议35:分清 staticmethod 和 classmethod 的适用场景
- 第4章 库
- 建议36:掌握字符串的基本用法
- 建议37:按需选择 sort() 或者 sorted()
- 建议38:使用 copy 模块深拷贝对象
- 建议39:使用 Counter 进行计数统计
- 建议40:深入掌握 ConfigParser
- 建议41:使用 argparse 处理命令行参数
- 建议42:使用 pandas 处理大型 CSV 文件
- 建议43:一般情况使用 ElementTree 解析 XML
- 建议44:理解模块 pickle 优劣
- 建议45:序列化的另一个不错的选择 JSON
- 建议46:使用 traceback 获取栈信息
- 建议47:使用 logging 记录日志信息
- 建议48:使用 threading 模块编写多线程程序
- 建议49:使用 Queue 使多线程编程更安全
- 第5章 设计模式
- 第6章 内部机制
- 建议54:理解 built-in objects
- 建议55:init() 不是构造方法
- 建议56:理解名字查找机制
- 建议57:为什么需要 self 参数
- 建议58:理解 MRO 与多继承
- 建议59:理解描述符机制
- 建议60:区别 getattr() 和 getattribute() 方法
- 建议61:使用更为安全的 property
- 建议62:掌握 metaclass
- 建议63:熟悉 Python 对象协议
- 建议64:利用操作符重载实现中缀语法
- 建议65:熟悉 Python 的迭代器协议
- 建议66:熟悉 Python 的生成器
- 建议67:基于生成器的协程及 greenlet
- 建议68:理解 GIL 的局限性
- 建议69:对象的管理与垃圾回收
- 第7章 使用工具辅助项目开发
- 第8章 性能剖析与优化
建议43:一般情况使用 ElementTree 解析 XML
xml.dom.minidom和xml.sax大概是Python中解析XML文件最广为人知的两个模块了,原因一是这两个模块自Python 2.0以来就成为Python的标准库;二是网上关于这两个模块的使用方面的资料最多。作为主要解析XML方法的两种实现,DOM需要将整个XML文件加载到内存中并解析为一棵树,虽然使用较为简单,但占用内存较多,性能方面不占优势,并且不够Pythonic;而SAX是基于事件驱动的,虽不需要全部装入XML文件,但其处理过程却较为复杂。实际上Python中对XML的处理还有更好的选择,ElementTree便是其中一个,一般情况下使用ElementTree便已足够。它从Python2.5开始成为标准模块,cElementTree是ElementTree的Cython实现,速度更快,消耗内存更少,性能上更占优势,在实际使用过程中应该尽量优先使用cElementTree。由于两者使用方式上完全兼容本文将两者看做一个物件,除非说明不再刻意区分。ElementTree在解析XML文件上具有以下特性:
使用简单。它将整个XML文件以树的形式展示,每一个元素的属性以字典的形式表示,非常方便处理。
内存上消耗明显低于DOM解析。由于ElementTree底层进行了一定的优化,并且它的iterparse解析工具支持SAX事件驱动,能够以迭代的形式返回XML部分数据结构,从而避免将整个XML文件加载到内存中,因此性能上更优化,相比于SAX使用起来更为简单明了。
支持XPath查询,非常方便获取任意节点的值。
这里需要说明的是,一般情况指的是:XML文件大小适中,对性能要求并非非常严格。如果在实际过程中需要处理的XML文件大小在GB或近似GB级别,第三方模块lxml会获得较优的处理结果。关于lxml模块的介绍请参考本章后续小节或者参考文章“使用由Python编写的lxml实现高性能XML解析”,可通过链接http://www.ibm.com/developerworks/cn/xml/x-hiperfparse/可以访问。
下面结合具体的实例来说明elementtree解析XML文件常用的方法。需要解析的XML实例如下:
<systems> <system platform="linux" name="linuxtest"> <purpose>automation test</purpose> <system_type>virtual</system_type> <ip_address/> <commands_on_boot> <command_details> <!-- Set root password. --> <command>echo root:mytestpwd | sudo /usr/ sbin/chpasswd</command> <userid>root2</userid> <password>Passw0rd</password> </command_details> <command_details> <command>mkdir /TEST; chmod 777 /TEST</command> </command_details> </commands_on_boot> </system> <system platform="aix" name="aixtest"> <purpose>manual test</purpose> <system_type>virtual</system_type> <ip_address/> <commands_on_boot> <command_details> <!-- Set root password. --> <command>echo root:mytestpwd | sudo /usr/ sbin/chpasswd</command> <userid>root2</userid> <password>Passw0rd</password> </command_details> <command_details> <command>mkdir /TEST; chmod 777 /TEST</command> </command_details> </commands_on_boot> </system> </systems>
模块ElementTree主要存在两种类型ElementTree和Element,它们支持的方法以及对应的使用示例如表4-1和表4-2所示。
表4-1 ElementTree主要的方法和使用示例
表4-2 Element主要的方法和使用示例
前面我们提到elementree的iterparse工具能够避免将整个XML文件加载到内存,从而解决当读入文件过大内存而消耗过多的问题。iterparse返回一个可以迭代的由元组(时间,元素)组成的流对象,支持两个参数——source和events,其中event有4种选择——start、end、startns和endns(默认为end),分别与SAX解析的startElement、endElement、startElementNS和endElementNS一一对应。
本节最后来看一下iterparse的使用示例:统计userid在整个XML出现的次数。
>>> count = 0 >>> for event,elem in ET.iterparse("test.xml"):# 对iterparse 的返回值进行迭代 ... if event =='end': ... if elem.tag =='userid': ... count+=1 ... elem.clear() ... >>> print count 2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论