是否有任何理由让类声明继承自object
?
我刚刚发现了一些执行此操作的代码,但我找不到合理的原因。
class MyClass(object):
# class code follows...
答案 0 :(得分:509)
Python 3.x:
class MyClass(object):
=新式班级
class MyClass:
=新样式类(隐式继承自对象)
Python 2.x:
class MyClass(object):
=新式班级
class MyClass:
= OLD-STYLE CLASS
在Python 3.x中定义基类时,可以从定义中删除对象。然而,这可以为严重难以追踪的问题打开大门......
Python在Python 2.2中引入了新式的类,到现在为止,旧式的类已经很老了。旧式课程的讨论是buried in the 2.x docs,而在3.x文档中则不存在。
问题是, Python 2.x中旧式类的语法与Python 3.x中新式类的替代语法相同。 Python 2.x仍然被广泛使用(例如GAE,Web2Py),并且任何代码(或编码器)无意中将3.x样式的类定义带入2.x代码将最终导致一些严重过时的基础对象。而且由于旧式课程并不在人们的视线之内,他们可能不会知道是什么打击了他们。
因此,只需将其拼出来,并为2.x开发人员留下眼泪。
答案 1 :(得分:484)
是否有任何理由让类声明继承自
object
?
tl; dr:在Python 3中,除了Python 2和3之间的兼容性之外,没有理由。在Python 2中,有很多原因。
在Python 2.x(从2.2开始)中,有两种类型的类,取决于object
是否存在作为基类:
“经典”风格类:它们没有object
作为基类:
>>> class ClassicSpam: # no base class
... pass
>>> ClassicSpam.__bases__
()
“新”样式类:它们直接或间接(例如从built-in type继承),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'>,)
毫无疑问,在编写课程时,总是想要参加新式课程。这样做的好处很多,列出其中一些:
Support for descriptors。具体来说,使用描述符可以实现以下结构:
classmethod
:一种接收类作为隐式参数而不是实例的方法。staticmethod
:一种不接收隐式参数self
作为第一个参数的方法。property
:创建用于管理属性的获取,设置和删除的功能。 __slots__
:节省了类的内存消耗,并且还可以加快属性访问速度。当然,它确实impose limitations。 __new__
静态方法:允许您自定义新类实例的创建方式。
Method resolution order (MRO):在尝试解析要调用的方法时,将以何种顺序搜索类的基类。
与MRO相关,super
calls。另请参阅super()
considered super.
如果您不继承object
,请忘记这些。可以找到前一个要点的更详尽的描述以及“新”样式类的其他特权here。
新式课程的缺点之一是课程本身对内存要求更高。但是,除非你创造了许多阶级对象,否则我怀疑这将是一个问题,并且在积极的海洋中是负面的。
在Python 3中,事情已经简化了。只存在新式类(明确称为类),因此,添加object
的唯一区别是要求您输入8个以上的字符。这样:
class ClassicSpam:
pass
完全等同于(除了他们的名字:-)到这个:
class NewSpam(object):
pass
以及:
class Spam():
pass
所有人object
都有__bases__
。
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
在Python 2中: 始终从object
显式继承。获得津贴。
在Python 3中:从object
继承,如果您正在编写试图与Python无关的代码,也就是说,它需要在Python 2和Python 3中工作。否则不要,因为Python在幕后为你插入它,所以没有任何区别。
答案 2 :(得分:394)
是的,这是一个'新风格'的对象。这是python2.2中引入的一个特性。
新样式对象与经典对象具有不同的对象模型,有些东西无法与旧样式对象一起正常工作,例如super()
,@property
和描述符。有关新样式类的详细说明,请参阅this article。
SO链接描述差异:What is the difference between old style and new style classes in Python?
答案 3 :(得分:30)
Learn Python the Hard Way的历史记录:
Python的一个类的原始演绎在许多严重的情况下被打破了 方法。当这个错误得到承认时已经太晚了, 他们不得不支持它。为了解决问题,他们需要 一些“新阶级”的风格使“老班”继续工作 但你可以使用新的更正确的版本。
他们决定使用一个“对象”这个词,它是低级的 您继承的“类”,以创建一个类。令人困惑, 但是一个类继承自名为“object”的类来创建一个类但是 它不是一个真正属于它的对象,但不要忘记继承 来自对象。
也只是为了让你知道新式类和旧式类之间的区别是什么,新式类总是继承自object
类或继承自object
的另一个类。 }:
class NewStyle(object):
pass
另一个例子是:
class AnotherExampleOfNewStyle(NewStyle):
pass
虽然旧式基类看起来像这样:
class OldStyle():
pass
一个旧式的儿童班看起来像这样:
class OldStyleSubclass(OldStyle):
pass
您可以看到Old Style基类不会从任何其他类继承,但是,Old Style类当然可以相互继承。从对象继承可确保每个Python类都具有某些功能。 Python 2.2中引入了新的样式类
答案 4 :(得分:27)
是的,它是historical。没有它,它会创建一个旧式的类。
如果在旧式对象上使用type()
,则只需获得“实例”。在一个新式的对象上,你得到它的类。
答案 5 :(得分:6)
类创建语句的语法:
class <ClassName>(superclass):
#code follows
如果没有您特别想要继承的任何其他超类,superclass
应始终为 object
,这是Python中所有类的根。
object
在技术上是&#34; new-style&#34;的根源。 Python中的类。但今天的新式课程与唯一的课程风格一样好。
但是,如果您在创建类时没有明确使用单词object
,那么正如其他人所提到的,Python 3.x隐式继承自object
超类。但我想明确总是比隐含(地狱)