为什么 Python 类会继承对象?

2022-01-30 00:00:00 python class oop inheritance object

问题描述

类声明是否有任何理由从 object 继承?

Is there any reason for a class declaration to inherit from object?

我刚刚找到了一些执行此操作的代码,但我找不到很好的理由.

I just found some code that does this and I can't find a good reason why.

class MyClass(object):
    # class code follows...


解决方案

类声明是否有任何理由从 object 继承?

在 Python 3 中,除了 Python 2 和 3 的兼容性之外,没有理由.在 Python 2 中,原因很多.

In Python 3, apart from compatibility between Python 2 and 3, no reason. In Python 2, many reasons.

在 Python 2.x(从 2.2 开始)中,有两种样式的类,具体取决于是否存在 object 作为基类:

In Python 2.x (from 2.2 onwards) there's two styles of classes depending on the presence or absence of object as a base-class:

  1. 经典"风格类:它们没有 object 作为基类:

  1. "classic" style classes: they don't have object as a base class:

>>> class ClassicSpam:      # no base class
...     pass
>>> ClassicSpam.__bases__
()

  • 新"样式类:它们直接或间接拥有(例如从内置类型),object作为基类:

  • "new" style classes: they have, directly or indirectly (e.g inherit from a built-in type), object as a base class:

    >>> class NewSpam(object):           # directly inherit from object
    ...    pass
    >>> NewSpam.__bases__
    (<type 'object'>,)
    >>> class IntSpam(int):              # indirectly inherit from object...
    ...    pass
    >>> IntSpam.__bases__
    (<type 'int'>,) 
    >>> IntSpam.__bases__[0].__bases__   # ... because int inherits from object  
    (<type 'object'>,)
    

  • 毫无疑问,在编写课程时,您会总是想要选择新式课程.这样做的好处很多,列举其中一些:

    Without a doubt, when writing a class you'll always want to go for new-style classes. The perks of doing so are numerous, to list some of them:

    • 对描述符的支持.具体来说,使用描述符可以实现以下构造:

    • Support for descriptors. Specifically, the following constructs are made possible with descriptors:

    1. classmethod:一种方法接收类作为隐式参数而不是实例.
    2. staticmethod:一种方法不接收隐式参数 self 作为第一个参数.
    3. 具有 property 的属性:创建用于管理属性的获取、设置和删除的功能.
    4. __slots__:节省内存消耗一个类,也导致更快的属性访问.当然,它确实施加限制.
    1. classmethod: A method that receives the class as an implicit argument instead of the instance.
    2. staticmethod: A method that does not receive the implicit argument self as a first argument.
    3. properties with property: Create functions for managing the getting, setting and deleting of an attribute.
    4. __slots__: Saves memory consumptions of a class and also results in faster attribute access. Of course, it does impose limitations.

  • __new__ 静态方法:让您自定义如何创建新的类实例.

  • The __new__ static method: lets you customize how new class instances are created.

    方法解析顺序(MRO):按什么顺序尝试解析调用哪个方法时,将搜索类的基类.

    Method resolution order (MRO): in what order the base classes of a class will be searched when trying to resolve which method to call.

    与 MRO 相关,super 调用.另请参阅,super() 被认为是超级的.

    Related to MRO, super calls. Also see, super() considered super.

    如果你不是从 object 继承的,忘记这些.可以在 这里.

    If you don't inherit from object, forget these. A more exhaustive description of the previous bullet points along with other perks of "new" style classes can be found here.

    新型类的缺点之一是类本身需要更多内存.但是,除非您要创建许多类对象,否则我怀疑这将是一个问题,并且它是在积极海洋中的消极沉没.

    One of the downsides of new-style classes is that the class itself is more memory demanding. Unless you're creating many class objects, though, I doubt this would be an issue and it's a negative sinking in a sea of positives.

    在 Python 3 中,事情被简化了.只有新样式的类存在(简单地称为类),所以添加 object 的唯一区别是要求您再输入 8 个字符.这个:

    In Python 3, things are simplified. Only new-style classes exist (referred to plainly as classes) so, the only difference in adding object is requiring you to type in 8 more characters. This:

    class ClassicSpam:
        pass
    

    完全等同于(除了他们的名字:-):

    is completely equivalent (apart from their name :-) to this:

    class NewSpam(object):
         pass
    

    对此:

    class Spam():
        pass
    

    所有的 __bases__ 中都有 object.

    >>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
    [True, True, True]
    

    <小时>

    那么,你应该怎么做?

    在 Python 2 中: 总是从 object 显式继承.获得福利.


    So, what should you do?

    In Python 2: always inherit from object explicitly. Get the perks.

    在 Python 3 中: 从 object 继承,如果您编写的代码试图与 Python 无关,也就是说,它需要在 Python 2 和 Python 中都可以工作3. 否则不要,真的没什么区别,因为Python会在幕后为你插入.

    In Python 3: inherit from object if you are writing code that tries to be Python agnostic, that is, it needs to work both in Python 2 and in Python 3. Otherwise don't, it really makes no difference since Python inserts it for you behind the scenes.

  • 相关文章