Python 类继承对象

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4015417/
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-08-18 13:51:49  来源:igfitidea点击:

Python class inherits object

pythonclassoopobjectinheritance

提问by tjvr

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

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

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

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

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

采纳答案by Dimitris Fasarakis Hilliard

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

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

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

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



Python 2.x story:

Python 2.x 故事:

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

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

  1. "classic" styleclasses: they don't have objectas a base class:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. "new" styleclasses: they have, directly or indirectly(e.g inherit from a built-in type), objectas 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'>,)
    
  1. “经典”样式类:它们没有object作为基类:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
  2. “新”样式类:它们直接或间接(例如从内置类型继承)object作为基类:

    >>> 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 alwayswant 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: 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 selfas 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.
  • The __new__static method: lets you customize how new class instances are created.

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

  • Related to MRO, supercalls. Also see, super()considered super.

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.

如果您不继承自object,请忘记这些。可以在此处找到对先前要点的更详尽描述以及“新”样式类的其他特权。

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.x story:

Python 3.x 故事:

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

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

class ClassicSpam:
    pass

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

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

class NewSpam(object):
     pass

and to this:

并为此:

class Spam():
    pass

All have objectin their __bases__.

object在他们的__bases__.

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


So, what should you do?

那你该怎么办?

In Python 2:always inherit from objectexplicitly. Get the perks.

在 Python 2 中:始终object显式继承自. 领取福利。

In Python 3:inherit from objectif 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.

在 Python 3 中:object如果您编写的代码试图与 Python 无关,即它需要在 Python 2 和 Python 3 中都可以工作,则继承自。否则不要这样做,因为 Python 会为您插入它,因此实际上没有区别在幕后。

回答by knitti

Yes, it's historical. Without it, it creates an old-style class.

是的,这是历史性的。没有它,它会创建一个旧式的类。

If you use type()on an old-style object, you just get "instance". On a new-style object you get its class.

如果您type()在旧式对象上使用,您只会得到“实例”。在新样式的对象上,您会得到它的类。

回答by Jerub

Yes, this is a 'new style' object. It was a feature introduced in python2.2.

是的,这是一个“新风格”对象。这是python2.2中引入的一个特性。

New style objects have a different object model to classic objects, and some things won't work properly with old style objects, for instance, super(), @propertyand descriptors. See this articlefor a good description of what a new style class is.

新风格的对象有不同的对象模型,以经典的对象,有些事情不会与旧的样式对象正常工作,例如super()@property和描述符。有关什么是新样式类的详细说明,请参阅本文

SO link for a description of the differences: What is the difference between old style and new style classes in Python?

用于描述差异的 SO 链接:Python 中旧样式和新样式类之间的区别是什么?

回答by Yarin

Python 3

蟒蛇 3

  • class MyClass(object):= New-style class
  • class MyClass:= New-style class (implicitly inherits from object)
  • class MyClass(object):= 新型类
  • class MyClass:= 新式类(隐式继承自object

Python 2

蟒蛇 2

  • class MyClass(object):= New-style class
  • class MyClass:= OLD-STYLE CLASS
  • class MyClass(object):= 新型类
  • class MyClass:=老式班级


Explanation:

说明

When defining base classes in Python 3.x, you're allowed to drop the objectfrom the definition. However, this can open the door for a seriously hard to track problem…

在 Python 3.x 中定义基类时,您可以object从定义中删除。然而,这可以为一个严重难以追踪的问题打开大门……

Python introduced new-style classes back in Python 2.2, and by now old-style classes are really quite old. Discussion of old-style classes is buried in the 2.x docs, and non-existent in the 3.x docs.

Python 在 Python 2.2 中引入了新式类,而现在旧式类真的很老了。旧式类的讨论被埋在 2.x 文档中,而在 3.x 文档中不存在。

The problem is, the syntax for old-style classes in Python 2.x is the same as the alternative syntax for new-style classes in Python 3.x. Python 2.x is still very widely used (e.g. GAE, Web2Py), and any code (or coder) unwittingly bringing 3.x-style class definitions into 2.x code is going to end up with some seriously outdated base objects. And because old-style classes aren't on anyone's radar, they likely won't know what hit them.

问题是,Python 2.x 中旧式类的语法与 Python 3.x 中新式类的替代语法相同。Python 2.x 仍然被广泛使用(例如 GAE、Web2Py),任何代码(或编码器)在不知不觉中将 3.x 风格的类定义引入 2.x 代码最终都会导致一些严重过时的基础对象。而且由于旧式课程不在任何人的关注范围内,他们可能不知道是什么打击了他们。

So just spell it out the long way and save some 2.x developer the tears.

所以只要把它拼写出来,就可以为一些 2.x 开发人员省去眼泪。

回答by disp_name

History from Learn Python the Hard Way:

艰难地学习 Python 的历史:

Python's original rendition of a class was broken in many serious ways. By the time this fault was recognized it was already too late, and they had to support it. In order to fix the problem, they needed some "new class" style so that the "old classes" would keep working but you can use the new more correct version.

They decided that they would use a word "object", lowercased, to be the "class" that you inherit from to make a class. It is confusing, but a class inherits from the class named "object" to make a class but it's not an object really its a class, but don't forget to inherit from object.

Python 对类的原始再现在许多严重的方面被破坏了。当这个错误被发现时已经太晚了,他们不得不支持它。为了解决这个问题,他们需要一些“新类”样式,以便“旧类”继续工作,但您可以使用新的更正确的版本。

他们决定将使用小写的“对象”一词作为您继承以创建类的“类”。令人困惑的是,一个类继承自名为“object”的类来创建一个类,但它并不是一个真正的类,但不要忘记从 object 继承。

Also just to let you know what the difference between new-style classes and old-style classes is, it's that new-style classes always inherit from objectclass or from another class that inherited from object:

同样只是为了让您知道新式类和旧式类之间的区别是什么,新式类总是从object类继承或从另一个继承自的 类object

class NewStyle(object):
    pass

Another example is:

另一个例子是:

class AnotherExampleOfNewStyle(NewStyle):
    pass

While an old-style base class looks like this:

虽然旧式基类看起来像这样:

class OldStyle():
    pass

And an old-style child class looks like this:

一个老式的子类看起来像这样:

class OldStyleSubclass(OldStyle):
    pass

You can see that an Old Style base class doesn't inherit from any other class, however, Old Style classes can, of course, inherit from one another. Inheriting from object guarantees that certain functionality is available in every Python class. New style classes were introduced in Python 2.2

您可以看到 Old Style 基类不会从任何其他类继承,但是,Old Style 类当然可以相互继承。继承自 object 保证某些功能在每个 Python 类中都可用。Python 2.2 中引入了新的样式类

回答by kmario23

The syntax of the class creation statement:

类创建语句的语法:

class <ClassName>(superclass):
    #code follows

In the absence of any other superclasses that you specifically want to inherit from, the superclassshould always be object, which is the root of all classes in Python.

如果没有您特别想要继承的任何其他超类,则superclass应该始终是object,它是 Python 中所有类的根。

objectis technically the root of "new-style" classes in Python. But the new-style classes today are as good as being the only style of classes.

object从技术上讲,它是 Python 中“新式”类的根源。但是今天的新式班级和唯一的班级一样好。

But, if you don't explicitly use the word objectwhen creating classes, then as others mentioned, Python 3.x implicitly inherits from the objectsuperclass. But I guess explicit is always better than implicit (hell)

但是,如果您object在创建类时没有明确使用这个词,那么正如其他人所提到的,Python 3.x 隐式继承自object超类。但我想显式总是比隐式更好(地狱)

Reference

参考