Python 3 中 class A: 与 class A(object): 完全等价,后者纯属冗余;所有类默认继承 object,支持 super()、__slots__ 等特性;显式写 (object) 仅在跨版本兼容或代码风格规范中有意义。

Python 3 中所有类自动继承 object,显式写 class A(object): 不改变任何行为,纯属冗余。
Python 3 的类默认就是新式类
只要你写 class A:,解释器就把它当作新式类处理,底层自动补上 object 作为基类。这和 Python 2 完全不同——在 Python 2 里不写 (object) 就是旧式类,super() 会直接报 TypeError: super() argument 1 must be type, not classobj。
现在你随便定义一个空类:
class Person:
pass
它的 Person.__mro__ 就已经是 (<class 'Person'>, <class 'object'>),super() 可用,__slots__ 生效,@property 正常工作——全都不依赖你手写 (object)。
立即学习“Python免费学习笔记(深入)”;
显式写 (object) 唯一可能起作用的场景
它只在跨版本兼容或代码信号层面有意义,不是功能需要:
- 代码还要跑在 Python 2.7 上:必须写,否则旧式类语义会崩
- 团队强制风格统一,比如 PEP 8 衍生规范要求“所有类显式声明基类”
- 避免被误读为“漏写了父类”:比如本该继承
Exception却只写了class MyError:,加个(object)至少表明“我 deliberate 这样写” - 某些静态检查器(如 mypy)对空继承提示模糊,显式写上能绕过警告
但注意:这些都不是运行时需求。在纯 Python 3 环境下,class A(object): 和 class A: 编译出的类对象完全一致,id(A) 都一样。
多重继承里再写 object 是典型冗余
如果已有父类(比如 class Base:)本身已隐式继承 object,那么 class Child(Base, object): 不但没用,还会让 Child.__bases__ 多出一个 object 元素,干扰对继承结构的直观理解。
更关键的是:Child.mro() 结果不会变——C3 算法保证 object 总在末尾,显式加它只是重复声明,不参与排序逻辑。
常见错误现象:
- 看到别人代码里写
class View(BaseView, object),跟着照抄,以为“更安全” - 用 IDE 自动生成类时勾选了“include base class”,结果批量塞进
(object) - 误以为不写
(object)就无法用isinstance(x, object)——其实所有对象都满足这个条件
真正容易被忽略的细节
很多人以为“不写 (object) 就少了什么”,其实问题常出在对 object 默认行为的预期偏差:
-
__init__没定义时,实际调用的是object.__init__(),它什么都不做——所以子类忘记调super().__init__()也不会报错,但父类初始化逻辑就丢了 -
__str__返回的是<__main__.A object at 0x...>,不重写的话日志全是内存地址,这不是继承问题,而是忘了覆盖默认实现 -
__eq__或__hash__重写时没调super().__eq__(other),可能破坏与object默认协议的一致性,导致集合操作异常
这些都不是“要不要写 (object)”的问题,而是对 object 提供的契约是否主动承接的问题。


















