Python中的旧风格和新风格类有什么区别?
Python中的旧风格和新风格类有什么区别? 这些日子里是否有过使用旧式课程的理由?
从http://docs.python.org/2/reference/datamodel.html#new-style-and-classic-classes:
在Python 2.1之前,老式的类是用户唯一可用的风格。 (old-style)类的概念与type的概念无关:如果x
是旧式类的实例,则x.__class__
指定x
的类,但type(x)
始终是<type 'instance'>
。 这反映了一个事实,即所有旧式实例独立于它们的类,都使用一种称为实例的内置类型实现。
Python 2.2引入了新类,以统一类和类型的概念 。 新式类只是一种用户定义的类型,不多也不少。 如果x是新样式类的实例,则type(x)
通常与x.__class__
相同(尽管这不能保证 - 新样式的类实例被允许覆盖为x.__class__
返回的值) 。
引入新式类的主要动机是提供一个完整的元模型的统一对象模型 。 它还具有许多直接的好处,例如能够对大多数内置类型进行子类化,或者引入可用于计算属性的“描述符”。
出于兼容性原因,类默认情况下仍然是旧式的 。 通过将另一个新样式类(即一个类型)指定为父类,或者如果不需要其他父类,则可以创建新样式类。 除了什么类型的返回之外,新风格类的行为与旧风格类的行为在许多重要细节中不同。 其中一些更改对于新对象模型来说很重要,就像特殊方法被调用的方式一样。 其他的是“修复”,在兼容性问题之前无法实现,比如多重继承情况下的方法解析顺序。
Python 3只有新风格的类 。 无论你是否从object
继承类,Python 3都是新类。
宣言明智的:
新风格的类继承自对象或其他新风格的类。
class NewStyleClass(object):
pass
class AnotherNewStyleClass(NewStyleClass):
pass
旧式课堂不。
class OldStyleClass():
pass
旧样式类和新样式类之间的重要行为变化
Exception
(下面的例子) __slots__
添加 MRO(方法解决顺序)已更改
在其他答案中提到过,但这里有一个经典MRO和C3 MRO(用于新风格类)之间区别的具体示例。
问题是在多重继承中搜索属性(包括方法和成员变量)的顺序。
经典类从左到右进行深度优先搜索。 第一场比赛停止。 他们没有__mro__
属性。
class C: i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 0
assert C21().i == 2
try:
C12.__mro__
except AttributeError:
pass
else:
assert False
新式课堂 MRO在单个英语句子中更加复杂。 这里详细解释。 它的一个属性是一个基类只在其所有派生类都被搜索过后才被搜索。 它们具有显示搜索顺序的__mro__
属性。
class C(object): i = 0
class C1(C): pass
class C2(C): i = 2
class C12(C1, C2): pass
class C21(C2, C1): pass
assert C12().i == 2
assert C21().i == 2
assert C12.__mro__ == (C12, C1, C2, C, object)
assert C21.__mro__ == (C21, C2, C1, C, object)
除非派生自Exception
否则不能引发新样式类对象
围绕Python 2.5可以提出很多类,在Python 2.6中被删除。 在Python 2.7.3上:
# OK, old:
class Old: pass
try:
raise Old()
except Old:
pass
else:
assert False
# TypeError, new not derived from `Exception`.
class New(object): pass
try:
raise New()
except TypeError:
pass
else:
assert False
# OK, derived from `Exception`.
class New(Exception): pass
try:
raise New()
except New:
pass
else:
assert False
# `'str'` is a new style object, so you can't raise it:
try:
raise 'str'
except TypeError:
pass
else:
assert False
链接地址: http://www.djcxy.com/p/1579.html
上一篇: What is the difference between old style and new style classes in Python?