导航:起始页 > Dive Into Python > 五分钟回顾 | << >> | ||||
深入 Python :Dive Into Python 中文版Python 从新手到专家 [Dip_5.4b_CPyUG_Release] |
学习 Python 的第一件事就是安装,不是吗?
在 Windows 上,安装 Python 有两种选择。
在 Mac OS X 上,对于安装 Python 有两种选择:安装或不安装。您可能想要安装它。
Mac OS 9 上没有预装任何版本的 Python,安装相对简单,只有一种选择。
在 http://www.python.org/ftp/python/ 选择列出的最新的版本号, 然后选择 其中的rpms/ 目录下载最新的 Python RPM 包。 使用 rpm 命令进行安装,操作如下所示:
如果您运行在 Debian GNU/Linux 上,安装 Python 需要使用 apt 命令。
如果您宁愿从源码创建,可以从 http://www.python.org/ftp/python/下载 Python 的源代码。选择最新的版本,下载.tgz 文件,执行通常的 configure, make, make install 步骤。
既然我们已经安装了 Python,那么我们运行的这个交互 shell 是什么东西呢?
您现在应该已经安装了一个可以工作的 Python 版本了。
这是一个完整的、可执行的 Python 程序。
与其它大多数语言一样 Python 有函数,但是它没有像 C++ 一样的独立的头文件;或者像 Pascal 一样的分离的 interface/implementation 段。在需要函数时,像下面这样声明即可:
可以通过给出一个 doc string (文档字符串) 来文档化一个 Python 函数。
在 Python 中,函数同其它东西一样也是对象。
Python 函数没有明显的 begin 和 end,没有标明函数的开始和结束的花括号。唯一的分隔符是一个冒号 (:),接着代码本身是缩进的。
所有的 Python 模块都是对象,并且有几个有用的属性。您可以使用这些属性方便地测试您所编写的模块。下面是一个使用 if __name__ 的技巧。
Dictionary 是 Python 的内置数据类型之一,它定义了键和值之间一对一的关系。
List 是 Python 中使用最频繁的数据类型。如果您对 list 仅有的经验就是在 Visual Basic 中的数组或 Powerbuilder 中的数据存储,那么就打起精神学习 Python 的 list 吧。
Tuple 是不可变的 list。一旦创建了一个 tuple,就不能以任何方式改变它。
Python 与大多数其它语言一样有局部变量和全局变量之分,但是它没有明显的变量声明。变量通过首次赋值产生,当超出作用范围时自动消亡。
Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。
Python 的强大特性之一是其对 list 的解析,它提供一种紧凑的方法,可以通过对 list 中的每个元素应用一个函数,从而将一个 list 映射为另一个 list。
您有了一个形如 key=value 的 key-value 对 list,并且想将它们合成为单个字符串。为了将任意包含字符串的 list 连接成单个字符串,可以使用字符串对象的 join 方法。
现在 odbchelper.py 程序和它的输出结果都应该非常清楚了。
下面是一个完整可运行的 Python 程序。大概看一下这段程序,你应该可以理解不少了。用数字标出的行阐述了 第 2 章 第一个 Python 程序 中涉及的一些概念。如果剩下来的代码看起来有点奇怪,不用担心,通过阅读本章你将会理解所有这些。
Python 允许函数参数有缺省值;如果调用函数时不使用参数,参数将获得它的缺省值。此外,通过使用命名参数还可以以任意顺序指定参数。SQL Server Transact/SQL 中的存储过程也可以做到这些;如果你是脚本高手,你可以略过这部分。
Python 有小部分相当有用的内置函数。除这些函数之外,其它所有的函数都被分到了各个模块中。其实这是一个非常明智的设计策略,避免了核心语言变得像其它脚本语言一样臃肿 (咳 咳,Visual Basic)。
你已经知道 Python 函数是对象。你不知道的是,使用 getattr 函数,可以得到一个直到运行时才知道名称的函数的引用。
如你所知,Python 具有通过列表解析 (第 3.6 节 “映射 list”) 将列表映射到其它列表的强大能力。这种能力同过滤机制结合使用,使列表中的有些元素被映射的同时跳过另外一些元素。
在Python 中,and 和 or 执行布尔逻辑演算,如你所期待的一样。但是它们并不返回布尔值,而是返回它们实际进行比较的值之一。
Python 支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做 lambda 的函数,是从 Lisp 借用来的,可以用在任何需要函数的地方。
最后一行代码是唯一还没有解释过的,它完成全部的工作。但是现在工作已经简单了,因为所需要的每件事都已经按照需求建立好了。所有的多米诺骨牌已经就位,到了将它们推倒的时候了。
apihelper.py 程序和它的输出现在应该非常清晰了。
下面是一个完整的,可运行的 Python 程序。请阅读模块、类和函数的 doc strings,可以大概了解这个程序所做的事情和工作情况。像平时一样,不用担心你不理解的东西,这就是本章其它部分将告诉你的内容。
Python 有两种导入模块的方法。两种都有用,你应该知道什么时候使用哪一种方法。一种方法,import module,你已经在第 2.4 节 “万物皆对象”看过了。另一种方法完成同样的事情,但是它与第一种有着细微但重要的区别。
Python 是完全面向对象的:你可以定义自已的类,从自已的或内置的类继承,然后从你定义的类创建实例。
在 Python 中对类进行实例化很直接。要对类进行实例化,只要调用类 (就好像它是一个函数),传入定义在 __init__ 方法中的参数。返回值将是新创建的对象。
如你所见,FileInfo 是一个有着像字典一样的行为方式的类。为了进一步揭示这一点,让我们看一看在 UserDict 模块中的 UserDict 类,它是我们的 FileInfo 类的父类。它没有什么特别的,也是用 Python 写的,并且保存在一个 .py 文件里,就像我们其他的代码。特别之处在于,它保存在你的 Python 安装目录的 lib 目录下。
除了普通的类方法,Python 类还可以定义专用方法。专用方法是在特殊情况下或当使用特别语法时由 Python 替你调用的,而不是在代码中直接调用 (像普通的方法那样)。
除了 __getitem__ 和 __setitem__ 之外 Python 还有更多的专用函数。某些可以让你模拟出你甚至可能不知道的功能。
你已经知道了数据属性,它们是被一个特定的类实例所拥有的变量。Python 也支持类属性,它们是由类本身所拥有的。
与大多数的语言不同,一个 Python 函数,方法,或属性是私有还是公有,完全取决于它的名字。
实打实的对象把戏到此为止。你将在 第 12 章 中看到一个真实世界应用程序的专有类方法,它使用 getattr 创建一个到远程 Web 服务的代理。
与许多面向对象语言一样,Python 具有异常处理,通过使用 try...except 块来实现。
Python 有一个内置函数,open,用来打开在磁盘上的文件。open 返回一个文件对象,它拥有一些方法和属性,可以得到被打开文件的信息,以及对被打开文件进行操作。
与其它大多数语言一样,Python 也拥有 for 循环。你到现在还未曾看到它们的唯一原因就是,Python 在其它太多的方面表现出色,通常你不需要它们。
与其它任何 Python 的东西一样,模块也是对象。只要导入了,总可以用全局 dictionary sys.modules 来得到一个模块的引用。
os.path 模块有几个操作文件和目录的函数。这里,我们看看如何操作路径名和列出一个目录的内容。
再一次,所有的多米诺骨牌都放好了。我们已经看过每行代码是如何工作的了。现在往回走一步,看一下放在一起是怎么样的。
在 第 5 章 介绍的 fileinfo.py 程序现在应该完全理解了。
如果你要解决的问题利用字符串函数能够完成,你应该使用它们。它们快速、简单且容易阅读,而快速、简单、可读性强的代码可以说出很多好处。但是,如果你发现你使用了许多不同的字符串函数和 if 语句来处理一个特殊情况,或者你组合使用了 split、join 等函数而导致用一种奇怪的甚至读不下去的方式理解列表,此时,你也许需要转到正则表达式了。
这一系列的例子是由我几年前日常工作中的现实问题启发而来的,当时我需要从一个老化系统中导出街道地址,在将它们导入新的系统之前,进行清理和标准化。(看,我不是只将这些东西堆到一起,它有实际的用处。)这个例子展示我如何处理这个问题。
你可能经常看到罗马数字,即使你没有意识到它们。你可能曾经在老电影或者电视中看到它们 (“版权所有 MCMXLVI” 而不是 “版权所有1946”),或者在某图书馆或某大学的贡献墙上看到它们 (“成立于 MDCCCLXXXVIII”而不是“成立于1888”)。你也可能在某些文献的大纲或者目录上看到它们。这是一个表示数字的系统,它实际上能够追溯到远古的罗马帝国 (因此而得名)。
在前面的章节,你处理了相同字符可以重复三次的情况。在正则表达式中,有另外一个方式来表达这种情况,并且能提高代码的可读性。首先看看我们在前面的例子中使用的方法。
迄今为止,你只是处理过被我称之为“紧凑”类型的正则表达式。正如你曾看到的,它们难以阅读,即使你清楚正则表达式的含义,你也不能保证六个月以后你还能理解它。你真正所需的就是利用内联文档 (inline documentation)。
迄今为止,你主要是匹配整个模式,不论是匹配上,还是没有匹配上。但是正则表达式还有比这更为强大的功能。当一个模式确实 匹配上时,你可以获取模式中特定的片断,你可以发现具体匹配的位置。
这只是正则表达式能够完成工作的很少一部分。换句话说,即使你现在备受打击,相信我,你也不是什么也没见过了。
我经常在 comp.lang.python 上看到关于如下的问题: “ 怎么才能从我的 HTML 文档中列出所有的 [头|图像|链接] 呢?” “怎么才能 [分析|解释|munge] 我的 HTML 文档的文本,但是又要保留标记呢?” “怎么才能一次给我所有的 HTML 标记 [增加|删除|加引号] 属性呢?” 本章将回答所有这些问题。
HTML 处理分成三步:将 HTML 分解成它的组成片段,对片段进行加工,接着将片段再重新合成 HTML。第一步是通过 sgmllib.py 来完成的,它是标准 Python 库的一部分。
为了从 HTML 文档中提取数据,将 SGMLParser 类进行子类化,然后对想要捕捉的标记或实体定义方法。
SGMLParser 自身不会产生任何结果。它只是分析,分析,再分析,对于它找到的有趣的东西会调用相应的一个方法,但是这些方法什么都不做。SGMLParser 是一个 HTML 消费者 (consumer):它接收 HTML,将其分解成小的、结构化的小块。正如您所看到的,在前一节中,您可以定义 SGMLParser 的子类,它可以捕捉特别标记和生成有用的东西,如一个网页中所有链接的一个列表。现在我们将沿着这条路更深一步。我们要定义一个可以捕捉 SGMLParser 所丢出来的所有东西的一个类,接着重建整个 HTML 文档。用技术术语来说,这个类将是一个 HTML 生产者 (producer)。
我们先偏离一下 HTML 处理的主题,讨论一下 Python 如何处理变量。Python 有两个内置的函数,locals 和 globals,它们提供了基于 dictionary 的访问局部和全局变量的方式。
有另外一种字符串格式化的形式,它使用 dictionary 而不是值的 tuple。
在 comp.lang.python 上的一个常见问题是 “我有一些 HTML 文档,属性值没有用引号括起来,并且我想将它们全部括起来,我怎么才能实现它呢?” [7] (一般这种事情的出现是由于一个项目经理加入到一个大的项目中来,而他又抱着 HTML 是一种标记语言的教条,要求所有的页面必须能够通过 HTML 校验器的验证。而属性值没有被引号括起来是一种常见的对 HTML 规范的违反。) 不管什么原因,未括起来的属性值通过将 HTML 送进 BaseHTMLProcessor 可以容易地修复。
Dialectizer 是 BaseHTMLProcessor 的简单 (和拙劣) 的派生类。它通过一系列的替换对文本块进行了处理,但是它确保在 <pre>...</pre> 块之间的任何东西不被修改地通过。
到了将迄今为止我们已经学过并用得不错的东西放在一起的时候了。我希望您专心些。
Python 向您提供了一个强大工具,sgmllib.py,可以通过将 HTML 结构转变为一种对象模型来进行处理。可以以许多不同的方式来使用这个工具。
处理 XML 有两种基本的方式。一种叫做 SAX (“Simple API for XML”),它的工作方式是,一次读出一点 XML 内容,然后对发现的每一个元素调用一个方法。(如果你读了 第 8 章 HTML 处理,这应该听起来很熟悉,因为这是 sgmllib 工作的方式。) 另一种方式叫做 DOM (“Document Object Model”),它的工作方式是,一次性读入整个 XML 文档,然后使用 Python 类创建一个内部表示形式 (以树结构进行连接)。Python 拥有这两种解析方式的标准模块,但是本章只涉及 DOM。
实际上解析一个 XML 文档是很简单的:只要一行代码。但是,在你接触那行代码前,需要暂时岔开一下,讨论一下包。
正如我说的,实际解析一个 XML 文档是非常简单的:只要一行代码。从这里出发到哪儿去就是你自己的事了。
Unicode 是一个系统,用来表示世界上所有不同语言的字符。当 Python 解析一个 XML 文档时,所有的数据都是以unicode的形式保存在内存中的。
通过一步步访问每一个节点的方式遍历 XML 文档可能很乏味。如果你正在寻找些特别的东西,又恰恰它们深深埋入了你的 XML 文档,有个捷径让你可以快速找到它:getElementsByTagName 。
XML 元素可以有一个或者多个属性,只要已经解析了一个 XML 文档,访问它们就太简单了。
以上就是 XML 的核心内容。下一章将使用相同的示例程序,但是焦点在于能使程序更加灵活的其它方面:使用输入流处理,使用 getattr 进行方法分发,并使用命令行标识允许用户重新配置程序而无需修改代码。
Python 的最强大力量之一是它的动态绑定,而动态绑定最强大的用法之一是类文件(file-like)对象。
UNIX 用户已经对标准输入、标准输出和标准错误的概念非常熟悉了。这一节是为其他不熟悉的人准备的。
kgp.py 使用了多种技巧,在你进行 XML 处理时,它们或许能派上用场。第一个就是,利用输入文档的结构稳定特征来构建节点缓冲。
解析 XML 文档时,另一个有用的己技巧是查找某个特定元素的所有直接子元素。例如,在语法文件中,一个 ref 元素可以有数个 p 元素,其中每一个都可以包含很多东西,包括其他的 p 元素。你只要查找作为 ref 孩子的 p 元素,不用查找其他 p 元素的孩子 p 元素。
第三个有用的 XML 处理技巧是将你的代码基于节点类型和元素名称分散到逻辑函数中。解析后的 XML 文档是由各种类型的节点组成的,每一个都是通过 Python 对象表示的。文档本身的根层次通过一个 Document 对象表示。Document 还包含了一个或多个 Element 对象 (表示 XML 标记),其中的每一个可以包含其它的 Element 对象、Text 对象 (表示文本),或者 Comment 对象 (表示内嵌注释)。使用 Python 编写分离各个节点类型逻辑的分发器非常容易。
Python 完全支持创建在命令行运行的程序,也支持通过命令行参数和短长样式来指定各种选项。这些并非是 XML 特定的,但是这样的脚本可以充分使用命令行处理,看来是时候提一下它了。
你已经了解很多基础的东西。让我们回来看看所有片段是如何整合到一起的。
Python 带有解析和操作 XML 文档非常强大的库。minidom 接收一个 XML 文件并将其解析为 Python 对象,并提供了对任意元素的随机访问。进一步,本章展示了如何利用 Python 创建一个“真实”独立的命令行脚本,连同命令行标志、命令行参数、错误处理,甚至从前一个程序的管道接收输入的能力。
在讲解如何下载 web 页和如何从 URL 解析 XML时,你已经学习了关于 HTML 处理和 XML 处理,接下来让我们来更全面地探讨有关 HTTP web 服务的主题。
假如说你想用 HTTP 下载资源,例如一个 Atom feed 汇聚。你不仅仅想下载一次;而是想一次又一次地下载它,如每小时一次,从提供 news feed 的站点获得最新的消息。让我们首先用一种直接而原始的方法来实现它,然后看看如何改进它。
这里有五个你必须关注的 HTTP 重要特性。
首先,让我们开启 Python HTTP 库的调试特性并查看网络线路上的传输过程。这对本章的全部内容都很有用,因为你将添加越来越多的特性。
改善你的 HTTP web 服务客户端的第一步就是用 User-Agent 适当地鉴别你自己。为了做到这一点,你需要远离基本的 urllib 而深入到 urllib2。
既然你知道如何在你的 web 服务请求中添加自定义的 HTTP 头信息,接下来看看如何添加 Last-Modified 和 ETag 头信息的支持。
你可以使用两种不同的自定义 URL 处理器来处理永久重定向和临时重定向。
你要支持的最后一个重要的 HTTP 特性是压缩。许多 web 服务具有发送压缩数据的能力,这可以将网络线路上传输的大量数据消减 60% 以上。这尤其适用于 XML web 服务,因为 XML 数据 的压缩率可以很高。
你已经看到了构造一个智能的 HTTP web 客户端的所有片断。现在让我们看看如何将它们整合到一起。
openanything.py 及其函数现在可以完美地工作了。
你用 Google,对吧?它是一个很流行的搜索引擎。你是否希望能以程序化的方式访问 Google 的搜索结果呢?现在你能做到了。下面是一个用 Python 搜索 Google 的程序。
与本书中的其他代码不同,本章依赖的库不是 Python 预安装的。
调用远程函数是 SOAP 的核心功能。有很多提供公开 SOAP 访问的服务器提供用于展示的简单功能。
SOAP 提供了一个很方便的方法用以查看背后的情形。
SOAPProxy 类本地方法调用并透明地转向到远程 SOAP 方法。正如你所看到的,这是很多的工作,SOAPProxy 快速和透明地完成他们。它没有做到的是提供方法自省的手段。
就像网络服务舞台上的所有事物,WSDL 也经历了一个充满明争暗斗而且漫长多变的历史。我不打算讲述这段令我伤心的历史。还有一些其他的标准提供相同的支持,但 WSDL 还是胜出,所以我们还是来学习一下如何使用它。
让我们回到这章开始时你看到的那段代码,获得比当前气温更有价值和令人振奋的信息。
是的,SOAP 网络服务的世界中也不总是欢乐和阳光。有时候也会有故障。
SOAP 网络服务是很复杂的,雄心勃勃的它试图涵盖网络服务的很多不同应用。这一章我们接触了它的一个简单应用。
在前面的章节中,通过阅读代码,你迅速“深入”,以最快的速度理解了各个程序。既然你已对 Python 有了一定的了解,那么接下来让我们看看程序开发之前 的工作。
现在你已经定义了你的转换程序所应有的功能,下面一步会有点儿出乎你的意料:你将要开发一个测试组件 (test suite) 来测试你未来的函数以确保它们工作正常。没错:你将为还未开发的程序开发测试代码。
这是将被开发并保存为 roman.py 的罗马数字转换程序的完整测试组件 (test suite)。很难立刻看出它们是如何协同工作的,似乎所有类或者方法之间都没有关系。这是有原因的,而且你很快就会明了。
单元测试的基础是构建独立的测试用例 (test case)。一个测试用例只回答一个关于被测试代码的问题。
使用有效输入确保函数成功通过测试还不够,你还需要测试无效输入导致函数失败的情形。但并不是任何失败都可以,必须如你预期地失败。
你经常会发现一组代码中包含互逆的转换函数,一个把 A 转换为 B ,另一个把 B 转换为 A。在这种情况下,创建“完备性检测”可以使你在由 A 转 B 再转 A 的过程中不会出现丢失精度或取整等错误。
到目前为止,单元测试已经完成,是时候开始编写被单元测试测试的代码了。你将分阶段地完成这个工作,因此开始时所有的单元测试都是失败的,但在逐步完成 roman.py 的同时你会看到它们一个个地通过测试。
现在你有了 roman 模块的大概框架,到了开始写代码以通过测试的时候了。
现在 toRoman 对于有效的输入 (1 到 3999 整数) 已能正确工作,是正确处理那些无效输入 (任何其他输入) 的时候了。
现在 toRoman 完成了,是开始编写 fromRoman 的时候了。感谢那个将每个罗马数字和对应整数关连的完美数据结构,这个工作不比 toRoman 函数复杂。
现在 fromRoman 对于有效输入能够正常工作了,是揭开最后一个谜底的时候了:使它正常工作于无效输入的情况下。这意味着要找出一个方法检查一个字符串是不是有效的罗马数字。这比 toRoman 中验证有效的数字输入困难,但是你可以使用一个强大的工具:正则表达式。
尽管你很努力地编写全面的单元测试,但是 bug 还是会出现。我所说的 “bug” 是什么呢?Bug 是你还没有编写的测试用例。
尽管你竭尽努力地分析你的客户,并点灯熬油地提炼出精确的需求,但需求还是会是不断变化。大部分客户在看到产品前不知道他们想要什么。即便知道,也不擅于精确表述出他们的有效需求。即便能表述出来,他们在下一个版本一定会要求更多的功能。因此你需要做好更新测试用例的准备以应对需求的改变。
全面的单元测试带来的最大好处不是你的全部测试用例最终通过时的成就感;也不是被责怪破坏了别人的代码时能够证明 自己的自信。最大的好处是单元测试给了你自由去无情地重构。
聪明的读者在学习前一节时想得会更深入一层。现在写的这个程序中最令人头痛的性能负担是正则表达式,但它是必需的,因为没有其它方法来识别罗马数字。但是,它们只有 5000 个,为什么不一次性地构建一个查询表来读取?不必用正则表达式凸现了这个主意的好处。你建立了整数到罗马数字查询表的时候,罗马数字到整数的逆向查询表也构建了。
单元测试是一个强大的概念,使用得当的话既可以减少维护成本又可以增加长期项目的灵活性。同样重要的是要意识到单元测试并不是“灵丹妙药”,也不是“银弹”。编写好的测试用例很困难,保持其更新更需要磨练 (特别是当顾客对修复严重的 Bug 大呼小叫之时)。单元测试不是其它形式测试的替代品,比如说功能性测试、集成测试以及可用性测试。但它切实可行且功效明显,一旦相识,你会反问为什么以往没有应用它。
在 第 13 章 单元测试 中,你学会了单元测试的哲学。在 第 14 章 测试优先编程 中你步入了 Python 基本的单元测试操作,在 第 15 章 重构 部分,你看到单元测试如何令大规模重构变得容易。本章将在这些程序样例的基础上,集中关注于超越单元测试本身的更高级的 Python 特有技术。
从命令行运行 Python 代码时,知道所运行代码在磁盘上的存储位置有时候是有必要的。
你已经熟识了应用列表解析来过滤列表。这里介绍的是达到相同效果的另一种令很多人感觉清晰的实现方法。
现在的你,可能正抓耳挠腮地狠想,为什么这样比使用 for 循环和直接调用函数好。这是一个非常好的问题。通常这是一个程序观问题。使用 map 和 filter 强迫你围绕数据进行思考。
好了,大道理谈够了。让我们谈谈动态导入模块吧。
你已经学习了足够的知识,现在来分析本章样例代码的前七行:读取一个目录并从中导入选定的模块。
regression.py 程序及其输出到现在应该很清楚了。
我想谈谈名词复数。还有,返回其它函数的函数,高级的正则表达式和生成器 (Generator)。生成器是 Python 2.3 新引入的。但首先还是让我们先来谈谈如何生成名词复数。
你所针对的单词 (至少在英语中) 是字符串和字符。你还需要规则来找出不同的字符 (字母) 组合,并对它们进行不同的操作。这听起来像是正则表达式的工作。
现在你将增加一个抽象过程。你从定义一个规则列表开始:如果这样,就做那个,否则判断下一规则。让我们暂时将程序一部分复杂化以便使另一部分简单化。
将每个匹配和规则应用分别制作成函数没有必要。你从来不会直接调用它们:你把它们定义于 rules 列表之中并从那里调用它们。让我们隐去它们的函数名而抓住规则定义的主线。
让我们精炼出代码中的重复之处,以便更容易地定义新规则。
你已经精炼了所有重复代码,也尽可能地把复数规则提炼到定义一个字符串列表。接下来的步骤是把这些字符串提出来放在另外的文件中,从而可以和使用它们的代码分开来维护。
现在你已准备好探讨生成器 (Generator) 了。
这一章中我们探讨了几个不同的高级技术。它们并不都适用于任何情况。
由于代码优化过程中存在太多的不明确因素,以至于你很难清楚该从何入手。
关于 Python 代码优化你需要知道的最重要问题是,决不要自己编写计时函数。
Soundex 函数的第一件事是检查输入是否是一个空字符串。怎样做是最好的方法?
Soundex 算法的第二步是依照特定规则将字符转换为数字。做到这点最好的方法是什么?
Soundex 算法的第三步是去除连续重复字符。怎样做是最佳方法?
Soundex 算法的最后一步是对短结果补零和截短长结果。最佳的做法是什么?
这一章展示了性能优化的几个重要方面,这里是就 Python 而言,但它们却普遍适用。
<< 进一步阅读 |
| | |
技巧和窍门 >> |