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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/332255/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 19:54:43  来源:igfitidea点击:

Difference between class foo and class foo(object) in Python

python

提问by

I know class foo(object)is an old school way of defining a class. But I would like to understand in more detail the difference between these two.

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

回答by Brian

Prior to python 2.2 there were essentially two different types of class: Those defined by C extensions and C coded builtins (types) and those defined by python class statements (classes). This led to problems when you wanted to mix python-types and builtin types. The most common reason for this is subclassing. If you wanted to subclass the list type in python code, you were out of luck, and so various workarounds were used instead, such as subclassing the pure python implementation of lists (in the UserList module) instead.

在 python 2.2 之前,本质上有两种不同类型的类:由 C 扩展和 C 编码的内置函数(类型)定义的类和由 python 类语句(类)定义的类。当您想混合使用 python 类型和内置类型时,这会导致问题。最常见的原因是子类化。如果您想在 Python 代码中对列表类型进行子类化,那么您就不走运了,因此使用了各种解决方法,例如对列表的纯 Python 实现(在 UserList 模块中)进行子类化。

This was a fairly ugly, so in 2.2 there was a moveto unify python and builtin types, including the ability to inheritfrom them. The result is "new style classes". These do have some incompatible differences to old-style classes however, so for backward compatability the bare class syntax creates an old-style class, while the new behaviour is obtained by inheriting from object. The most visible behaviour differences are:

这是相当丑陋的,所以在 2.2 中有一个统一 python 和内置类型的举措,包括从它们继承的能力。结果是“新样式类”。然而,这些与旧式类确实有一些不兼容的差异,因此为了向后兼容,裸类语法创建了一个旧式类,而新行为是通过从 object. 最明显的行为差异是:

  • The method resolution order (MRO). There is a difference in behaviour in diamond-shaped inheritance hierarchies (where A inherits from both B and C, which both inherit from a common base class D. Previously, methods were looked up left-to right, depth first (ie A B D C D) However if C overloads a member of D, it won't be used by A (as it finds D's implementation first) This is bad for various styles of programming (eg. using mixin classes). New style classes will treat this situation as A B C D, (look at the __mro__attribute of a class to see the order it will search)

  • The __new__constructor is added, which allows the class to act as a factory method, rather than return a new instance of the class. Useful for returning particular subclasses, or reusing immutable objects rather than creating new ones without having to change the creation interface.

  • Descriptors. These are the feature behind such things as properties, classmethods, staticmethods etc. Essentially, they provide a way to control what happens when you access or set a particular attribute on a (new style) class.

  • 方法解析顺序 (MRO)。菱形继承层次结构中的行为存在差异(其中 A 继承自 B 和 C,两者都继承自一个共同的基类 D。以前,方法是从左到右查找,深度优先(即 ABDCD)但是如果 C 重载了 D 的一个成员,它就不会被 A 使用(因为它首先找到了 D 的实现)这对各种编程风格都是不利的(例如使用 mixin 类)。新风格的类会将这种情况视为 ABCD, (查看__mro__类的属性以查看它将搜索的顺序)

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

  • 描述符。这些是属性、类方法、静态方法等背后的功能。本质上,它们提供了一种方法来控制在您访问或设置(新样式)类上的特定属性时发生的情况。

回答by Brian C. Lane

class foo(object):is the 'new' way of declaring classes.

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

This change was made in python 2.2, see this PEP for an explanationof the differences.

此更改是在 python 2.2 中进行的,有关差异的解释,请参阅此 PEP

回答by muhuk

Subclassing objectyields a new-style class. Two well known advantages of new-style classes are:

子类化object产生一个新样式的类。新式类的两个众所周知的优点是:

  • Metaclasses (like class factories, but works transparently)
  • Properties (getters & setters...)
  • 元类(类似于类工厂,但透明地工作)
  • 属性(getter 和 setter...)

回答by Anroop

Referring to thisThe object in class Foo(object) is meant to make your python 3 code compatible with python 2 and 3.

参考这个Foo(object) 类中的对象是为了让你的 python 3 代码与 python 2 和 3 兼容。