美文网首页
旧式类 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