在Python 3.x中,继承Python的object类是否必要或有用?

108

在旧版Python中,当你创建一个类时,可以继承自object。据我所知,object是一种特殊的内置Python元素,它使你的类成为新式类。

那么对于更新的版本(> 3.0和2.6)呢?我在谷歌上搜索了object类,但由于明显的原因,结果太多了。


2
如果你的代码也会在2.x下使用,最好是明确说明。 - smci
2
这个问题在这里得到了很好的回答:https://dev59.com/hG865IYBdhLWcg3wCqHI - nngeek
同意;主要问题现在与版本无关,因此这是一个重复的问题。 - Karl Knechtel
2个回答

118

在Python 3中,您无需从 object 继承就可以拥有新的样式。所有类都是新式类。


9
请注意,在Python 3.1中,所有类都继承自object,无论是否显式地在类定义中使用(object) - u0b34a0f6ae
9
你不必这样做,但是“将Python代码移植到Python 3”文档表明它仍然有效:http://docs.python.org/py3k/howto/pyporting.html#subclass-object 另外请参考:http://docs.python.org/reference/datamodel.html#new-style-and-classic-classes - hyperboreean
从nngeek的评论中提到的这篇文章中,似乎一个很好的稳定参考资料来区分旧式和新式类(只适用于Py2)是:https://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes - 上述链接似乎已经发生了变化。 - Eric Cousineau

93

我知道这是一个老问题,但值得注意的是即使在Python 3中,这两个东西并不完全相同。

如果你明确地继承自object,那么你实际上是从builtins.object继承的,无论此时指向什么。

因此,我可能有一些(非常古怪的)模块出于某个原因覆盖了对象。我们将这个第一个模块称为“newobj.py”:

import builtins

old_object = builtins.object  # otherwise cyclic dependencies

class new_object(old_object):

    def __init__(self, *args, **kwargs):
        super(new_object, self).__init__(*args, **kwargs)
        self.greeting = "Hello World!" 

builtins.object = new_object  #overrides the default object

然后在另一个文件中("klasses.py"):

class Greeter(object):
    pass

class NonGreeter:
    pass

然后,在第三个文件中(我们实际上可以运行):

import newobj, klasses  # This order matters!

greeter = klasses.Greeter()
print(greeter.greeting)  # prints the greeting in the new __init__

non_greeter = klasses.NonGreeter()
print(non_greeter.greeting) # throws an attribute error

你可以看到,在明确继承自 object 时,我们得到的行为与允许隐式继承时不同。


19
这很相关,因为通常期望行为是等价的。但它并不等价,因此就有了我的观察。 - Philip Adler
12
当别人删除他们的评论,以至于看起来你在自言自语时,你难道不感到很讨厌吗? - Philip Adler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接