- 第 1 章 安装 Python
- 1.2. Windows 上的 Python
- 1.3. Mac OS X 上的 Python
- 1.4. Mac OS 9 上的 Python
- 1.5. RedHat Linux 上的 Python
- 1.6. Debian GNU/Linux 上的 Python
- 1.7. 从源代码安装 Python
- 1.8. 使用 Python 的交互 Shell
- 1.9. 小结
- 第 2 章 第一个 Python 程序
- 2.2. 函数声明
- 2.3. 文档化函数
- 2.4. 万物皆对象
- 2.5. 代码缩进
- 2.6. 测试模块
- 第 3 章 内置数据类型
- 3.2. List 介绍
- 3.3. Tuple 介绍
- 3.4. 变量声明
- 3.5. 格式化字符串
- 3.6. 映射 list
- 3.7. 连接 list 与分割字符串
- 3.8. 小结
- 第 4 章 自省的威力
- 4.2. 使用可选参数和命名参数
- 4.3. 使用 type、str、dir 和其它内置函数
- 4.4. 通过 getattr 获取对象引用
- 4.5. 过滤列表
- 4.6. and 和 or 的特殊性质
- 4.7. 使用 lambda 函数
- 4.8. 全部放在一起
- 4.9. 小结
- 第 5 章 对象和面向对象
- 5.2. 使用 from module import 导入模块
- 5.3. 类的定义
- 5.4. 类的实例化
- 5.5. 探索 UserDict: 一个封装类
- 5.6. 专用类方法
- 5.7. 高级专用类方法
- 5.8. 类属性介绍
- 5.9. 私有函数
- 5.10. 小结
- 第 6 章 异常和文件处理
- 6.2. 与文件对象共事
- 6.3. for 循环
- 6.4. 使用 sys.modules
- 6.5. 与 Directory 共事
- 6.6. 全部放在一起
- 6.7. 小结
- 第 7 章 正则表达式
- 7.2. 个案研究:街道地址
- 7.3. 个案研究:罗马字母
- 7.4. 使用{n,m} 语法
- 7.5. 松散正则表达式
- 7.6. 个案研究: 解析电话号码
- 7.7. 小结
- 第 8 章 HTML 处理
- 8.2. sgmllib.py 介绍
- 8.3. 从 HTML 文档中提取数据
- 8.4. BaseHTMLProcessor.py 介绍
- 8.5. locals 和 globals
- 8.6. 基于 dictionary 的字符串格式化
- 8.7. 给属性值加引号
- 8.8. dialect.py 介绍
- 8.9. 全部放在一起
- 8.10. 小结
- 第 9 章 XML 处理
- 9.2. 包
- 9.3. XML 解析
- 9.4. Unicode
- 9.5. 搜索元素
- 9.6. 访问元素属性
- 9.7. Segue
- 第 10 章 Scripts 和 Streams
- 10.2. 标准输入、输出和错误
- 10.3. 缓冲节点查询
- 10.4. 查找节点的直接子节点
- 10.5. 通过节点类型创建独立的处理句柄 Creating separate handlers by node type
- 10.6. 处理命令行参数
- 10.7. 全部放在一起
- 10.8. 小结
- 第 11 章 HTTP Web 服务
- 11.2. 避免通过 HTTP 重复地获取数据
- 11.3. HTTP 的特性
- 11.4. 调试 HTTP web 服务
- 11.5. 设置 User-Agent
- 11.6. 处理 Last-Modified 和 ETag
- 11.7. 处理重定向
- 11.8. 处理被压缩的数据
- 11.9. 全部放在一起
- 11.10. 小结
- 第 12 章 SOAP Web 服务
- 12.2. 安装 SOAP 库
- 12.3. 步入 SOAP
- 12.4. SOAP 网络服务查错
- 12.5. WSDL 介绍
- 12.6. 以 WSDL 进行 SOAP 内省
- 12.7. 搜索 Google
- 12.8. SOAP 网络服务故障排除
- 12.9. 小结
- 第 13 章 单元测试
- 13.2. 深入
- 13.3. 介绍 romantest.py
- 13.4. 正面测试(Testing for success)
- 13.5. 负面测试(Testing for failure)
- 13.6. 完备性检测(Testing for sanity)
- 第 14 章 以测试优先为原则的编程
- 14.2. roman.py, 第 2 阶段
- 14.3. roman.py, 第 3 阶段
- 14.4. roman.py, 第 4 阶段
- 14.5. roman.py, 第 5 阶段
- 第 15 章 重构
- 15.2. 应对需求变化
- 15.3. 重构
- 15.4. 后记
- 15.5. 小结
- 第 16 章 有效编程(Functional Programming)
- 16.2. 找到路径
- 16.3. 过滤已访问列表
- 16.4. 关联已访问列表
- 16.5. 数据中心思想编程
- 16.6. 动态导入模块
- 16.7. 全部放在一起
- 16.8. 小结
- 第 17 章 动态函数
- 17.2. plural.py, 第 1 阶段
- 17.3. plural.py, 第 2 阶段
- 17.4. plural.py, 第 3 阶段
- 17.5. plural.py, 第 4 阶段
- 17.6. plural.py, 第 5 阶段
- 17.7. plural.py, 第 6 阶段
- 17.8. 小结
- 第 18 章 性能优化
- 18.2. 使用 timeit 模块
- 18.3. 优化正则表达式
- 18.4. 优化字典查找
- 18.5. 优化列表操作
- 18.6. 优化字符串操作
- 18.7. 小结
- 附录 A. 进一步阅读
- 附录 B. 五分钟回顾
- 附录 C. 技巧和窍门
- 附录 D. 示例清单
- 附录 E. 修订历史
- 附录 F. 关于本书
- 附录 G. GNU Free Documentation License
- G.1. Applicability and definitions
- G.2. Verbatim copying
- G.3. Copying in quantity
- G.4. Modifications
- G.5. Combining documents
- G.6. Collections of documents
- G.7. Aggregation with independent works
- G.8. Translation
- G.9. Termination
- G.10. Future revisions of this license
- G.11. How to use this License for your documents
- 附录 H. Python license
- H.B. Terms and conditions for accessing or otherwise using Python
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
10.5. 通过节点类型创建独立的处理句柄 Creating separate handlers by node type
10.5. 通过节点类型创建独立的处理句柄 Creating separate handlers by node type
第三个有用的 XML 处理技巧是将你的代码基于节点类型和元素名称分散到逻辑函数中。解析后的 XML 文档是由各种类型的节点组成的,每一个都是通过 Python 对象表示的。文档本身的根层次通过一个Document对象表示。Document还包含了一个或者多个Element对象(for actual XML tags),其中的每一个可以包含其它的Element对象,Text对象(for bits of text),或者Comment对象(for embedded comments)。 Python 使编写分离每个节点类型逻辑的分发器非常容易。
例 10.17. 已解析 XML 对象的类名
>>> from xml.dom import minidom >>> xmldoc = minidom.parse('kant.xml') >>> xmldoc <xml.dom.minidom.Document instance at 0x01359DE8> >>> xmldoc.__class__ <class xml.dom.minidom.Document at 0x01105D40> >>> xmldoc.__class__.__name__ 'Document'
暂时假设kant.xml在当前目录中。 | |
正如你在第 9.2 节 “包”中看到的,解析 XML 文档返回的对象是一个Document对象,就像在xml.dom包的minidom.py中定义的一样。又如你在第 5.4 节 “类的实例化”中看到的,__class__是每个 Python 对象的一个内置属性。 | |
此外,__name__是每个 Python 类的内置属性,是一个字符串。这个字符串并不神秘;它和你在定义类时输入的类名相同。(参见第 5.3 节 “类的定义”。) |
好,现在你能够得到任何特定 XML 节点的类名了(因为每个 XML 节点都是以一个 Python 对象表示的)。你怎样才能利用这点来分离解析每个节点类型的逻辑呢?答案就是 getattr,你第一次见它是在第 4.4 节 “通过 getattr 获取对象引用”中。
例 10.18. parse, 一个通用的 XML 节点分发器
def parse(self, node): parseMethod = getattr(self, "parse_%s" % node.__class__.__name__) parseMethod(node)
First off, 注意你正在基于传入节点(在node参数中)的类名构造一个较大的字符串。所以如果你传入一个Document节点,你就构造了字符串'parse_Document',其它类同于此。 | |
现在你可以把这个字符串当作一个函数名称,然后通过 getattr 得到函数自身的引用。 | |
最后,你可以调用函数并将节点自身作为参数传入。下一个例子将展示每个函数的定义。 |
例 10.19. parse分发者调用的函数
def parse_Document(self, node): self.parse(node.documentElement) def parse_Text(self, node): text = node.data if self.capitalizeNextWord: self.pieces.append(text[0].upper()) self.pieces.append(text[1:]) self.capitalizeNextWord = 0 else: self.pieces.append(text) def parse_Comment(self, node): pass def parse_Element(self, node): handlerMethod = getattr(self, "do_%s" % node.tagName) handlerMethod(node)
parse_Document只会被调用一次,因为在一个 XML 文档中只有一个Document节点,并且在已解析 XML 的表示中只有一个Document对象。它只是turn around并解析语法文件的根元素。 | |
parse_Text 在节点表示文本时被调用。这个函数本身做某种特殊处理,自动将句子的第一个单词进行大写处理,而不是简单的将表示的文本追加到一个列表中。 | |
parse_Comment 只有一个pass,因为你并不关心语法文件中嵌入的注释。但是注意,你还是要定义这个函数并显式的让它不做任何事情。如果这个函数不存在,通用parse函数在遇到一个注释的时候,会执行失败,因为它试图找到并不存在的parse_Comment函数。为每个节点类型定义独立的函数,甚至你不要使用的,将会使通用parse函数保持简单和沉默。 | |
parse_Element方法其实本身就是一个分发器,它基于元素的标记名称。这个基本概念是相同的:使用元素的区别(它们的标记名称)然后针对每一个分发到一个独立的函数。你构建了一个类似于'do_xref'的字符串(对<xref>标记而言),找到这个名称的函数,并调用它。对其它的标记名称在解析语法文件的时候都可以找到类似的函数(<p>标记,<choice>标记)。 |
在这个例子中,分发函数parse和parse_Element只是找到相同类中的其它方法。如果你进行的处理过程很复杂(或者你有很多不同的标记名称),你可以将代码分散到独立的模块中,然后使用动态导入的方式导入每个模块并调用你需要的任何函数。动态导入将在第 16 章 有效编程(Functional Programming)中介绍。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论