Python 更新

作者:Andrew Kuchling

自从 J. Bauer 在《Linux Journal》第 35 期发表文章以来,Python 有哪些进展?像大多数自由软件一样,Python 正在不断地开发和增强。在最初的文章发表时,Python 的版本号是 1.2,1.3 的 beta 版本正在流传。从那时起,1.3 版本已正式发布,但很快在 10 月下旬被 1.4 版本取代。

1.3 和 1.4 版本都为该语言添加了新功能。1.3 中真正重要的新功能是向函数添加了关键字参数,类似于 Modula-3 的功能。例如,如果我们有以下函数定义

def curse(subject="seven large chickens",
          verb="redecorate",
          object="rumpus room"):
    print "May", subject, verb, "your", object

那么以下调用都是合法的

curse()
curse('a spaniel', 'pour yogurt on', 'hamburger')
curse(object='garage')
curse('the silent majority', object='Honda')
不以关键字开头的参数以通常的方式传递;非关键字参数和关键字参数可以在同一个函数调用中使用,只要非关键字参数在关键字参数之前即可。根据该规则,以下调用是语法错误
curse(object='psychoanalyst', 'a ancient philosopher')
以下调用将在运行时导致错误,因为一个参数被定义了两次
curse('the silent majority', subject='Honda')
作为一个令人愉快的副作用,添加关键字参数需要优化函数调用,将单个函数调用的开销减少约 20%。

1.4 版本中的大多数更改使 Python 更适用于数值任务。许多更改是由矩阵特殊兴趣小组(或 Matrix-SIG)的成员提出的,该小组定义了一种语法并构建了一种用于操作矩阵的数据类型。(Python SIG 是专注于 Python 的一个应用程序的小组,例如数值编程或数据库接口;有关现有 SIG 的更多信息,请参见 https://pythonlang.cn/sigs/。)

其中一项增强功能是对复数的支持。复数的虚部用后缀“J”或“j”表示;因此,-1 的平方根表示为 1j。当然,通常的数学运算(如加法和乘法)可以在复数上执行。

>>> 1+2j*2
(1+4j)
>>> (1+2j)*2
(2+4j)
>>> (1+2j)/(2+1j)
(0.8+0.6j)

复数的出现还需要可以对其执行操作的数学函数。没有更新现有的 math 模块,而是添加了一个名为 cmath 的新模块;如果操作返回了期望出错的复数值,则旧软件可能会发生故障。因此,math.sqrt(-1) 始终会引发 ValueError 异常,而 cmath.sqrt(-1) 将返回复数结果 1j。

>>> import cmath
>>> cmath.sqrt(-1)
1j
>>> a=cmath.log(1+2j)
>>> print a
(0.804718956217+1.10714871779j)
>>> cmath.exp(a)
(1+2j)
为了方便习惯 Fortran 表示法的用户,添加了 ** 运算符来计算幂;它只是 Python 现有 pow() 函数的简写形式。例如,10**2 等同于 pow(10,2) 并返回 100。

一个较小的新函数是由 comp.lang.python 中的几个人请求的。Python 长期以来都有一个 tuple() 函数,该函数将序列类型(如字符串或列表)转换为元组;将序列类型转换为列表的常用方法是 map(None, L)。 (函数 map(F,S) 返回一个列表,其中包含函数 F 的结果,该函数对序列 S 的每个元素执行。如果 F 为 None,就像在本例中一样,则除了将元素放入列表之外,不对元素执行任何操作。)

许多人发现这种不对称性——存在 tuple(),但不存在 list()——令人恼火。在 1.4 中,添加了 list() 函数,它与 tuple() 对称。

>>> tuple([1,2,3])
(1, 2, 3)
>>> list( (1,2,3,4) )
[1, 2, 3, 4]

1.4 中包含一个实验性功能,引起了很多争议:属于类实例的私有数据稍微更私有化了。一个例子将有助于解释更改的效果。考虑以下类

class A:
    def __init__(self):
        self.__value=0
    def get(self): return self.__value
    def set(self, newval): self.__value=newval
Python 不支持类中的私有数据,除非按照约定。通常的约定是私有变量的名称以至少一个下划线开头。但是,类的用户可以无视这一点并仍然访问私有值。例如
>>> instance=A()
>>> dir(instance)  # List all the attributes of the instance
['__value']
>>> instance.get()
0
>>> instance.__value=5
>>> instance.get()
5
一个更重要的问题;假设您对 A 的实现一无所知,并尝试创建一个 A 的子类,该子类添加一个使用其自己的私有 __value 属性的新方法。名称的两种用法将发生冲突。在 1.4 中情况略有不同
>>> instance=A()
>>> dir(instance)
['_A__value']
这个新值从哪里来的?在 1.4 中,任何以两个下划线开头的属性都将更改为带有前缀 _ 和类名。假设您有一个名为 File 的类,并且一个方法引用了一个名为 __mode 的私有变量,则该名称将更改为 _File__mode
>>> instance.get()
0
>>> instance.__value=5
>>> instance.get()
0
>>> dir(instance)
['_A__value', '__value']
现在,这仍然不能提供铁壁般的数据隐藏;调用者仍然可以显式地引用 _A__value。但是,A 的子类不再会意外地踩到属于 A 的私有变量。

此功能仍然存在争议,并在引入时在 comp.lang.python 中引起了很多争论。因此,它的状态仅为实验性,并且可能会在语言的未来版本中删除,因此依赖它是不明智的。

1.3 和 1.4 版本都包含一些新模块作为 Python 库的一部分,以及对库中现有模块的错误修复和修订。这些更改中的大多数仅对为这些模块的早期版本编写代码的人员感兴趣;有关所有详细信息,请参见 Python 源代码发行版中的文件 Misc/NEWS。如果您刚开始学习该语言,则这些更改实际上对您不感兴趣。

新闻不仅限于软件。关于 Python 的前两本书于 10 月出版:《Programming Python》,作者 Mark Lutz,《Internet Programming with Python》,作者 Aaron Watters、Guido van Rossum 和 James C. Ahlstrom。至少还有一本书计划于明年发布。

已经举办了两次 Python 研讨会,一次是去年五月在加利福尼亚州劳伦斯利弗莫尔国家实验室,另一次是十一月在华盛顿特区。演讲者讨论了各种主题:分布式对象;C++ 和 Python 或 Fortran 和 Python 的接口;以及 Web 编程。有关研讨会和提交的论文的更多信息,请参见 https://pythonlang.cn/workshops/。

1996 年 11 月,第五届 Python 研讨会与 FedUnix '96 贸易展览会联合举办。最常见的两个主题是数值编程和 Web 相关编程。对于数值工作,人们对使用 Python 作为胶水语言来控制用 Fortran 或 C++ 编写的数学函数库非常感兴趣。代码可以在 Python 中快速开发,一旦程序逻辑正确,就可以为了速度而将其移植到编译语言。使用像 Python 这样的通用编程语言而不是专门的数学语言也有好处;使用 Tk 编写的 GUI 或 CGI 接口可以更轻松地访问数值代码。

另一个热门话题是 Web 相关编程。Python Object Publisher 是一个特别有趣的系统,它允许通过 HTTP 访问 Python 对象。以 Object Publisher 演示文稿中的一个示例为例,类似这样的 URL

http://www.here.com/Car/Pinto/purchase?name=Bob

将导致定位名为 Pinto 的 Python Car 对象,并且将使用 'Bob' 作为参数调用其 purchase() 方法。其他演示文稿讨论了生成 HTML、编写用于系统管理的工具以及协作文档处理。有关论文的简要说明,请访问 https://pythonlang.cn/workshops/1996-11/,其中包含指向 HTML 或 PostScript 版本的链接。

当您阅读本文时,下一个研讨会的计划可能正在进行中,尽管在撰写本文时没有消息;有关当前状态,请参见 Python 网站。过去,会议一直在美国东部和西部之间交替举行,因此第六届研讨会可能将在西海岸举行。

参考文献

加载 Disqus 评论