旧式类 vs. 新式类(三)
目录.png转载须注明出处:简书@Orca_J35
4. 重要差异
引入新式类的主要动机是为了提供具有完整元模型(meta-model)的统一对象模型。新式类还具备许多实用功能:可将大多数内置类型子类化、引入了"描述符(descriptors)"等。
新式类和旧式类除了 type()
的返回值不同以外,两者在许多重要的细节上也拥有完全不同的行为。"新对象模型"与"旧对象模型"相比,一些行为拥有根本性的差异,比如调用特殊方法的方式。另外,"新对象模型"还对之前的部分行为进行"修正(fixes)",比如在多重继承中的方法解析顺序。
-
内置函数
super
仅支持新式类 -
新式类支持描述符(descriptors),可阅读 【译】Python描述符指南
-
新式类支持装饰器(decorators) - introduced in Python 2.4
-
新式类支持静态方法和类方法
-
新式类增加了
__new__
方法 -
新式类增加了
__getattribute__()
方法 -
新式类增加了
__slots__
方法 -
properties (computed attributes)
-
MRO 的算法更新,可阅读 Method Resolution Order - Python 见闻志
Classic classes do a depth first search from left to right. Stop on first match. They do not have the
__mro__
attribute.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
New-style classes
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
的新式类。# in Python 2.7 # 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
6. 术语
classic class
in Glossary of Python 2
Any class which does not inherit from object
. See new-style class. Classic classes have been removed in Python 3.
new-style class
Any class which inherits from object
. This includes all built-in types like list
and dict
. Only new-style classes can use Python's newer, versatile features like __slots__
, descriptors, properties, and __getattribute__()
, class methods, and static methods.
More information can be found in New-style and classic classes.