美文网首页
旧式类 vs. 新式类(三)

旧式类 vs. 新式类(三)

作者: import_hello | 来源:发表于2018-09-24 17:16 被阅读0次

    转载须注明出处:简书@Orca_J35

    目录.png

    4. 重要差异

    引入新式类的主要动机是为了提供具有完整元模型(meta-model)的统一对象模型。新式类还具备许多实用功能:可将大多数内置类型子类化、引入了"描述符(descriptors)"等。

    新式类和旧式类除了 type() 的返回值不同以外,两者在许多重要的细节上也拥有完全不同的行为。"新对象模型"与"旧对象模型"相比,一些行为拥有根本性的差异,比如调用特殊方法的方式。另外,"新对象模型"还对之前的部分行为进行"修正(fixes)",比如在多重继承中的方法解析顺序。

    新式类较旧式类的重要差异如下:[1] [2]

    • 内置函数 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.

    7. 扩展阅读

    8. 注脚

    赞赏.jpg
    1. What is the difference between old style and new style classes in Python?

    2. The Inside Story on New-Style Classes

    相关文章

      网友评论

          本文标题:旧式类 vs. 新式类(三)

          本文链接:https://www.haomeiwen.com/subject/mdxfoftx.html