为什么下面的类声明继承自对象?
class MyClass(object):
...
为什么下面的类声明继承自对象?
class MyClass(object):
...
当前回答
类声明从对象继承有什么原因吗?
在Python 3中,除了Python 2和3之间的兼容性之外,没有任何原因。在Python 2中,有很多原因。
Python 2.x故事:
在Python2.x(从2.2开始)中,有两种类型的类,这取决于是否存在作为基类的对象:
“经典”样式类:它们没有对象作为基类:>>>class ClassicSpam:#无基类通过>>>ClassicSpam__基础__()“新”样式类:它们直接或间接(例如从内置类型继承)将对象作为基类:>>>class NewSpam(object):#直接从对象继承通过>>>新垃圾邮件__基础__(<type'object'>,)>>>class IntSpam(int):#间接继承自对象。。。通过>>>IntSpam__基础__(<type‘int‘>,)>>>IntSpam__bases_[0]__bases__#。。。因为int继承自对象(<type'object'>,)
毫无疑问,当你写一门课的时候,你总是想去上新式的课。这样做的好处很多,列举其中一些:
支持描述符。具体而言,使用描述符可以实现以下构造:classmethod:将类作为隐式参数而不是实例接收的方法。staticmethod:不接收隐式参数self作为第一个参数的方法。带属性的财产:创建用于管理属性的获取、设置和删除的函数。__slots_:节省类的内存消耗,并加快属性访问速度。当然,它确实带来了限制。__new__静态方法:允许您自定义如何创建新的类实例。方法解析顺序(MRO):当试图解析要调用的方法时,将按什么顺序搜索类的基类。与MRO、超级呼叫相关。另请参见,super()被认为是super。
若你们并没有继承自对象,那个就忘掉这些。这里可以找到对前面要点的更详尽的描述以及“新”样式类的其他好处。
新型类的缺点之一是类本身对内存要求更高。但是,除非您正在创建许多类对象,否则我怀疑这会是一个问题,而且这是一个积极的海洋中的消极下沉。
Python 3.x故事:
在Python 3中,事情被简化了。只有新型类存在(简单地称为类),所以,添加对象的唯一区别是需要您再键入8个字符。这:
class ClassicSpam:
pass
完全等同于(除了名称:-):
class NewSpam(object):
pass
为此:
class Spam():
pass
所有的__bases__中都有对象。
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
那么,你该怎么办?
在Python 2中:始终显式继承自对象。享受额外津贴。
在Python3中:如果您编写的代码试图与Python无关,那么继承自对象,也就是说,它需要同时在Python2和Python4中工作。否则就不要了,因为Python在幕后为您插入了它,所以它真的没有什么区别。
其他回答
类声明从对象继承有什么原因吗?
在Python 3中,除了Python 2和3之间的兼容性之外,没有任何原因。在Python 2中,有很多原因。
Python 2.x故事:
在Python2.x(从2.2开始)中,有两种类型的类,这取决于是否存在作为基类的对象:
“经典”样式类:它们没有对象作为基类:>>>class ClassicSpam:#无基类通过>>>ClassicSpam__基础__()“新”样式类:它们直接或间接(例如从内置类型继承)将对象作为基类:>>>class NewSpam(object):#直接从对象继承通过>>>新垃圾邮件__基础__(<type'object'>,)>>>class IntSpam(int):#间接继承自对象。。。通过>>>IntSpam__基础__(<type‘int‘>,)>>>IntSpam__bases_[0]__bases__#。。。因为int继承自对象(<type'object'>,)
毫无疑问,当你写一门课的时候,你总是想去上新式的课。这样做的好处很多,列举其中一些:
支持描述符。具体而言,使用描述符可以实现以下构造:classmethod:将类作为隐式参数而不是实例接收的方法。staticmethod:不接收隐式参数self作为第一个参数的方法。带属性的财产:创建用于管理属性的获取、设置和删除的函数。__slots_:节省类的内存消耗,并加快属性访问速度。当然,它确实带来了限制。__new__静态方法:允许您自定义如何创建新的类实例。方法解析顺序(MRO):当试图解析要调用的方法时,将按什么顺序搜索类的基类。与MRO、超级呼叫相关。另请参见,super()被认为是super。
若你们并没有继承自对象,那个就忘掉这些。这里可以找到对前面要点的更详尽的描述以及“新”样式类的其他好处。
新型类的缺点之一是类本身对内存要求更高。但是,除非您正在创建许多类对象,否则我怀疑这会是一个问题,而且这是一个积极的海洋中的消极下沉。
Python 3.x故事:
在Python 3中,事情被简化了。只有新型类存在(简单地称为类),所以,添加对象的唯一区别是需要您再键入8个字符。这:
class ClassicSpam:
pass
完全等同于(除了名称:-):
class NewSpam(object):
pass
为此:
class Spam():
pass
所有的__bases__中都有对象。
>>> [object in cls.__bases__ for cls in {Spam, NewSpam, ClassicSpam}]
[True, True, True]
那么,你该怎么办?
在Python 2中:始终显式继承自对象。享受额外津贴。
在Python3中:如果您编写的代码试图与Python无关,那么继承自对象,也就是说,它需要同时在Python2和Python4中工作。否则就不要了,因为Python在幕后为您插入了它,所以它真的没有什么区别。
是的,这是历史性的。如果没有它,它将创建一个老式类。
如果对旧样式对象使用type(),则只需获得“instance”。在一个新型对象上,您可以得到它的类。
Python 3
class MyClass(对象):=新样式类class MyClass:=新样式类(隐式继承自对象)
Python 2
class MyClass(对象):=新样式类class MyClass:=OLD-STYLE类
说明:
在Python3.x中定义基类时,允许从定义中删除对象。然而,这可能会为严重难以追踪的问题打开大门…
Python在Python2.2中引入了新的类,到目前为止,旧式类已经非常陈旧了。对旧式类的讨论被隐藏在2.x文档中,而在3.x文档中则不存在。
问题是,Python 2.x中旧式类的语法与Python 3.x中新式类的替代语法相同。Python 2.x仍然被广泛使用(例如GAE、Web2Py),任何代码(或编码器)无意中将3.x样式类定义引入2.x代码中都会导致一些严重过时的基本对象。而且,由于老式课程不在任何人的视野中,他们很可能不知道是什么击中了他们。
所以,只要把它拼出来,省去一些2.x开发者的眼泪。
类创建语句的语法:
class <ClassName>(superclass):
#code follows
如果没有您特别希望从中继承的任何其他超类,则超类应该始终是对象,这是Python中所有类的根。
对象在技术上是Python中“新型”类的根源。但今天的新式阶级已经成为唯一的阶级。
但是,如果在创建类时没有显式使用object这个词,那么正如其他人提到的那样,Python3.x隐式继承自对象超类。但我想显性总是比隐性好(地狱)
参考
艰难学习Python的历史:
Python对一个类的原始呈现在许多严重方面被破坏方法。当这个故障被识别出来时,已经太晚了,为了解决这个问题,他们需要一些“新班级”的风格,以便“旧班级”继续工作但您可以使用更正确的新版本。他们决定使用小写的“对象”一词从中继承以创建类的“类”。这令人困惑,但是类继承自名为“object”的类它不是一个对象,实际上是一个类,但不要忘记继承来自对象。
同样,为了让您知道新式类和旧式类之间的区别,新式类总是从对象类或从从对象继承的另一个类继承:
class NewStyle(object):
pass
另一个例子是:
class AnotherExampleOfNewStyle(NewStyle):
pass
虽然老式基类看起来像这样:
class OldStyle():
pass
一个老式的儿童班是这样的:
class OldStyleSubclass(OldStyle):
pass
您可以看到,OldStyle基类不会从任何其他类继承,但是,OldStyle类当然可以彼此继承。从对象继承可以保证某些功能在每个Python类中都可用。Python 2.2中引入了新的样式类