Python中class foo和class foo(object)的区别

77

我知道class foo(object)是定义类的一种老式方法。但我想更加详细地了解这两者之间的区别。


你正在使用哪个版本的Python?从2.6/3.0的角度来看,情况是一样的。但是对于2.5(及以前)的版本来说,情况则不同。你现在使用的是哪个版本? - S.Lott
2
可能是Python中旧式类和新式类的区别是什么?的重复问题。 - vaultah
2
@Wendy 看起来你已经思考了几年,所以能否选择一个答案呢?甚至社区已经提出了建议。;-) - Zak
这里有一个全面的答案。链接 - Benyamin Jafari
4个回答

52
在Python 2.2之前,基本上有两种不同类型的类:由C扩展和C编码内置(types)定义的类,以及由Python类语句(classes)定义的类。这导致了问题,当您想要混合使用Python-types和内置类型时。最常见的原因是子类化。如果您想在Python代码中子类化列表类型,则无法实现,因此使用了各种解决方法,例如子类化列表的纯Python实现(在UserList模块中)。
这相当丑陋,因此在2.2中有一个移动以统一Python和内置类型,包括从它们继承的能力。结果是“新样式类”。然而,这些与旧样式类有一些不兼容的差异,因此为了向后兼容性,裸类语法创建旧样式类,而通过继承object获得新行为。最明显的行为差异是:
  • 方法解析顺序(MRO)。在菱形继承层次结构中(A同时从B和C继承,它们都从一个公共基类D继承),行为会有所不同。以前,方法是从左到右,深度优先查找的(即A B D C D)。但是如果C重载了D的成员,则A不会使用它(因为它首先找到了D的实现)。这对于各种编程风格很不好(例如使用混入类)。新式类将把此情况视为A B C D(查看类的__mro__属性以查看它将搜索的顺序)

  • __new__构造函数被添加,它允许类作为工厂方法,而不是返回类的新实例。有用于返回特定的子类,或重用不可变对象而无需更改创建接口。

  • 描述符。这是支持属性、classmethods、staticmethods等的功能。本质上,它们提供了一种控制在(新式)类上访问或设置特定属性时会发生什么的方法。


13

class foo(object):是声明类的“新”方法。

这个改变是在Python 2.2版本中进行的。请参阅这个PEP详细解释差异。


5
更准确的说法是“声明新式类的方法”。顺便提一下,从Python 3.0开始,“class foo:”就是一个新式类。 - Toni Ruža

6

继承object可以创建新式类。新式类有两个著名的好处:

  • 元类(像类工厂,但是工作起来更透明)
  • 属性(获取器和设置器...)

1
实际上,元类也适用于旧式类。某些属性功能也可以使用(getter,但不包括setter)。 - Brian

4

参考这里 在Foo类中的对象旨在使你的Python 3代码与Python 2和3兼容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接