19. 为什么引入新式类?

原文by Guido van Rossum 2009-6-21 翻译by kant


1. 问题

之前我曾说过,Python 中的类是后面加上去的,而其具体实现方式,则完全是 Python 所谓“抄近道”哲学的典型例子。随着语言的逐步演进,越来越多的高阶用户开始吐槽这种实现方式导致的种种问题。

其中一个问题就是,用户无法继承 Python 的内置类型。因此,比如列表、字典、字符串等类型,就和其它用户自定义类型不同,用户无法通过继承来自定义一些行为。对于一门自称是“面向对象”的语言来说,这个限制是非常奇怪的。

另一个问题是,用户自定义类的类型管理机制似乎也有问题。比如说,如果我们创建对象 a 和 b,即使对象 b 其实是另一个类的实例,type(a) == type(b) 也会返回 True。对于熟悉 C++ 和 Java 的用户来说,这也是很奇怪的,因为一般来说,类与底层类型系统是紧密绑定的。


2. 重写

在 Python 2.2 版本,我终于下定决心重写类的实现。这次重写可以说是当时为止,对 Python 主要子系统进行的最大一次重写——大家感觉我可能犯了某种“第二系统综合症”(second-system syndrome)。

这次重写不仅解决了内置类型无法继承的问题,而且支持了元类,修改了多重继承时很不成熟的方法解析顺序,并增加了许多其它特性。

这次重写主要受《Putting Metaclasses to Work》的影响, Ira Forman 和 Scott Danforth 写的这本书让我对元类的概念有了具体的理解。Python 中的元类与 Smalltalk 中的类似概念有所不同。

不过,当时新式类只是作为一种新特性引入的,并没有直接替换经典类。事实上,为了向后兼容,在 Python 2 的所有版本中,用户创建的类的默认都是经典类,如果要创建新式类,必须继承另一个新式类,比如 object (所有新式类的父类),比如说:


    ''class A(object):
    '' statements
    '' ...


3. 结果

新式类的引入非常成功。元类的概念受到了框架作者们的欢迎,并且因为类的行为变得更为一致,类的概念也变得更加清晰,向后兼容又让用户在使用新式类时,不用调整原有代码。

最后,虽然 Python 终将抛弃经典类,用户们却在这个过程中适应了继承 object 的写法,通过“class MyClass(object)”来声明一个类,这也没什么不好的吧。


发表评论

评论列表,共 0 条评论