Python类继承对象

tjv*_*jvr 1095 python oop inheritance class object

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

我刚刚发现了一些代码,我找不到一个很好的理由.

class MyClass(object):
    # class code follows...
Run Code Online (Sandbox Code Playgroud)

Jim*_*ard 614

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

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


Python 2.x故事:

在Python 2.x中(从2.2开始),根据是否存在object基类,有两种类型的类:

  1. "经典"样式类:它们没有object基类:

    >>> class ClassicSpam:      # no base class
    ...     pass
    >>> ClassicSpam.__bases__
    ()
    
    Run Code Online (Sandbox Code Playgroud)
  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'>,)
    
    Run Code Online (Sandbox Code Playgroud)

毫无疑问,在编写课程时,您总是希望选择新课程.这样做的好处很多,列出其中一些:

如果你不继承object,请忘记这些.可以在此处找到对前一个要点的更详尽描述以及"新"样式类的其他特权.

新式课程的缺点之一是课程本身对内存要求更高.但是,除非你创造了许多阶级对象,否则我怀疑这将是一个问题,并且它在积极的海洋中是负面的沉没.


Python 3.x故事:

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

class ClassicSpam:
    pass
Run Code Online (Sandbox Code Playgroud)

是完全相同的(除了他们的名字:-)到这个:

class NewSpam(object):
     pass
Run Code Online (Sandbox Code Playgroud)

对此:

class Spam():
    pass
Run Code Online (Sandbox Code Playgroud)

object他们都有__bases__.

>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
Run Code Online (Sandbox Code Playgroud)

那你该怎么办?

在Python 2中: 始终从object显式继承.获得额外津贴.

在Python 3中:object如果你正在编写试图与Python无关的代码,那就继承了,也就是说,它需要在Python 2和Python 3中都能工作.否则,它实际上没有区别,因为Python为你插入它在幕后.

  • 太糟糕的stackoverflow只有upvote = upvote + 1这些有点答案,希望我能做upvote + = N (3认同)

Yar*_*rin 523

Python 3.x:
class MyClass(object): = new-style class
class MyClass:= new-style class(隐式继承自object)

Python 2.x:
object = new-style class
class MyClass(object):= OLD-STYLE CLASS

说明:

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

Python在Python 2.2中引入了新式类,到现在为止,旧式类确实很老了.旧式课程的讨论隐藏在2.x文档中,并且在3.x文档中不存在.

问题是,Python 2.x中旧式类的语法与Python 3.x中新式类的替代语法相同.Python的2.X还是很广泛的应用(如GAE,web2py中),以及任何代码(或编码器)无意中把3.X风格的类定义为2.x的代码将一些严重过时的基本对象,以结束.而且由于旧式课程并不在人们的视线之内,他们可能不会知道是什么打击了他们.

因此,只需拼出它就可以节省一些2.x开发人员的眼泪.

  • "在Python 3.x中定义基类时,你可以从定义中删除对象.但是,这可以为严重难以跟踪的问题打开大门......"你提到了什么问题? (11认同)
  • @Aidis:我认为他们的意思是Py2和Py3上运行的代码在Py3上都可以正常运行,但如果它依赖于新式的类功能,可以在Py2上运行.就个人而言,如果我正在编写这样的代码,我省略了显式继承,只是将`__metaclass__ = type`放在模块的顶部(在`from __future__ import absolute_import,division,print_function`行:-)之后); 它是Py2中的兼容性黑客,默认情况下使模块中所有后续定义的类都是新式的,而在Py3中,它完全被忽略(只是一个随机的全局变量),所以它是无害的. (6认同)
  • 现在 Python 2 已经过时了,把它们从轨道上炸掉吗? (3认同)

Jer*_*rub 397

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

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

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

  • +1这个.请注意,旧式类在Python 3中已经消失了,因此您只需要继承Python 2中的`object`. (109认同)
  • 这不是一个真正的答案.ı只是参考其他文章.我认为Yarin的答案应该被接受作为这个问题的答案. (9认同)
  • @alwbtc:这个答案也有新的东西。例如,提到“ super()”使我想到了另一个重要的地方[http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods)。 (2认同)

dis*_*ame 30

艰难的方式学习Python的历史:

Python的一个类的原始演绎以许多严肃的方式被打破.当这个错误得到承认时已经太晚了,他们不得不支持它.为了解决这个问题,他们需要一些"新类"风格,以便"旧类"继续工作,但你可以使用新的更正确的版本.

他们决定使用一个"对象"这个词,小写,是你继承的"阶级"来制作一个班级.这很令人困惑,但是一个类继承自名为"object"的类来创建一个类,但它不是一个对象,它实际上是一个类,但不要忘记从对象继承.

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

class NewStyle(object):
    pass
Run Code Online (Sandbox Code Playgroud)

另一个例子是:

class AnotherExampleOfNewStyle(NewStyle):
    pass
Run Code Online (Sandbox Code Playgroud)

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

class OldStyle():
    pass
Run Code Online (Sandbox Code Playgroud)

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

class OldStyleSubclass(OldStyle):
    pass
Run Code Online (Sandbox Code Playgroud)

您可以看到Old Style基类不从任何其他类继承,但是,Old Style类当然可以相互继承.从对象继承可确保每个Python类都具有某些功能.Python 2.2中引入了新的样式类

  • 调用根类`object`并不是那么令人困惑,实际上它非常标准.Smalltalk有一个名为`Object`的根类,以及一个名为`Class`的根元类.为什么?因为,就像`Dog`是狗的类一样,`Object`是对象的类,而`Class`是类的类.Java,C#,ObjC,Ruby以及当今人们使用的具有根类的大多数其他基于类的OO语言都使用"Object"的某些变体作为名称,而不仅仅是Python. (7认同)

kni*_*tti 28

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

如果您type()在旧式对象上使用,则只需获得"实例".在一个新式的对象上你得到它的类.


kma*_*o23 6

类创建语句的语法:

class <ClassName>(superclass):
    #code follows
Run Code Online (Sandbox Code Playgroud)

在没有您特别想要继承的任何其他超类的情况下,superclass应始终是object,这是Python中所有类的根.

object从技术上讲,它是Python中"新式"类的根源.但今天的新式课程与唯一的课程风格一样好.

但是,如果你object在创建类时没有明确地使用这个词,那么正如其他人提到的那样,Python 3.x隐式地继承了object超类.但我想明确总是好于隐含(地狱)

参考