【问题标题】:Should all Python classes extend object? [duplicate]所有 Python 类都应该扩展对象吗? [复制]
【发布时间】:2013-02-28 18:29:39
【问题描述】:

我发现以下两项都有效:

class Foo():
    def a(self):
        print "hello"

class Foo(object):
    def a(self):
        print "hello"

所有 Python 类都应该扩展对象吗?不扩展对象有什么潜在的问题吗?

【问题讨论】:

标签: python inheritance


【解决方案1】:

是的,所有 Python 类都应该扩展(或者更确切地说是子类,这里是 Python)对象。虽然通常不会出现严重的问题,但在某些情况下(如多重继承树),这将很重要。这也确保了与 Python 3 更好的兼容性。

【讨论】:

  • 确切地说,从技术上讲,如果您不这样做,您将获得一个经典课程,但这并没有真正的优势,而且 python 3 也不支持它
  • 我很好奇为什么它会提高与 python3 的兼容性。据我了解,python3 会让它自动扩展对象,即使你没有指定它,对吧?
  • @PaulLo 对,但是如果你明确地从对象继承,你将在 Python 2 和 Python 3 上获得相同的(新样式)行为。这不是改变 Python 3 的方式的问题工作,这是在 Python 2 上使用前向兼容性的问题。
  • 这个建议看起来不是很优雅,但如果你解决 Python2 和 Python3 的问题,它似乎很有效。但它在实践中的相关性如何?
  • @Wolf 这取决于你在做什么。如果你有复杂的继承树,它就非常重要。如果你想让你的类成为一个描述符,你必须使用 new-style。如果您想了解更深入的信息,可以点击stackoverflow.com/questions/54867/… 的链接。
【解决方案2】:

在 Python 3 中,类隐式扩展 object,无论你自己是否这么说。

在 Python 2 中,有 old-style and new-style 类。要表明一个类是新式的,您必须显式地从object 继承。如果不是,则使用旧式实现。

你通常想要一个新式的类。显式继承 object。请注意,这也适用于旨在与 Python 2 兼容的 Python 3 代码。

【讨论】:

  • 是的,区别Free Foo pointed out,已经消失了,顺便说一句:are the empty parentheses optional?
  • 有很多使用 foo(object): 的 python 3 代码。那么这只是一个约定吗?
  • @RFVenter 它可能是应该在 Python 2 和 3 下运行的代码,在这种情况下,您需要显式地对对象进行子类化,以使该类在 Python 2 下的行为基本相同。跨度>
  • @blubberdiblub 这就是我所怀疑的,但我们的项目仅在 python 3.5 virtualenv 上运行。我认为代码一定是从 python 2 项目中复制的。
  • @RFVenter 是的,这可能是另一种解释。当然,如果现在只是 Python 3.x,那么摆脱对象引用就可以了。
【解决方案3】:

在 python3 中没有区别,但在 python2 中不扩展 object 会给你一个老式的类;您想使用新式类而不是旧式类。

【讨论】:

  • 这个答案是合理的,但其他回答者更快和/或更详细地到达那里;这个答案并没有为页面增加任何价值。
【解决方案4】:

在 Python 2 中,不从 object 继承将创建一个旧式类,除其他效果外,它还会导致 type 给出不同的结果:

>>> class Foo: pass
... 
>>> type(Foo())
<type 'instance'>

对比

>>> class Bar(object): pass
... 
>>> type(Bar())
<class '__main__.Bar'>

此外,多重继承的规则是different,我什至不想在这里总结。我看到的所有关于 MI 的优秀文档都描述了新型类。

最后,旧式类在 Python 3 中消失了,从 object 的继承变得隐含。因此,除非您需要与旧软件向后兼容,否则总是更喜欢新样式的类。

【讨论】:

    【解决方案5】:

    在 python 3 中,您可以通过三种不同的方式创建一个类,并且在内部它们都是相等的(参见示例)。不管你如何创建一个类,python 3 中的所有类都继承自称为 object 的特殊类。 object 类是 python 中的基础类,提供了很多功能,如双下划线方法、描述符、super() 方法、property() 方法等。

    示例 1。

    class MyClass:
     pass
    

    示例 2。

    class MyClass():
     pass
    

    示例 3。

    class MyClass(object):
      pass
    

    【讨论】:

    • 严格来说这不是真的...stackoverflow.com/questions/1238606/…
    • 我不确定我是否关注你。是的,在相关之前,可能与大多数人无关。
    • @PhilipAdler 通常认为object 引用了内置的object。如果我们必须考虑到任何 CPython 的内置标识符都可以被替换,我们几乎无法对数据模型做出一些断言。是否可以认真争论str 并不总是接受字符串作为参数,因为可以分配builtins.str = None
    • 我不断看到这种说法,即这是“广泛假设的”,并且我接受这是每个当前实现都做出的假设(这不是语言的要求),这不是我的我遇到的大多数 Python 程序员都假设,知道,甚至考虑过这一点。无论如何,即使它是正确的,通常假设它的断言也不会使我关于等价不是严格正确的断言无效。
    【解决方案6】:

    正如其他答案所涵盖的那样,Python 3 从对象继承是隐式的。但他们没有说明你应该做什么以及什么是约定。

    Python 3 文档示例都使用以下约定样式,因此我建议您在 Python 3 中的任何未来代码中都遵循此样式。

    class Foo:
        pass
    

    来源:https://docs.python.org/3/tutorial/classes.html#class-objects

    引用示例:

    类对象支持两种操作:属性引用 和实例化。

    属性引用使用用于所有属性的标准语法 Python 中的引用:obj.name。有效的属性名称都是 类对象被命名时在类的命名空间中的名称 创建。因此,如果类定义如下所示:

    class MyClass:
        """A simple example class"""
        i = 12345
    
        def f(self):
            return 'hello world'
    

    另一个引用:

    一般来说,实例变量是为每个唯一的数据 实例和类变量用于共享的属性和方法 类的所有实例:

    class Dog:
    
        kind = 'canine'         # class variable shared by all instances
    
        def __init__(self, name):
            self.name = name    # instance variable unique to each instance
    

    【讨论】:

      猜你喜欢
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2013-12-26
      • 1970-01-01
      • 2015-09-07
      • 1970-01-01
      相关资源
      最近更新 更多