目 录
3.1 super() 相当于 super(__class__, )
3.2 super(type) : 创建一个未绑定 super 对象
3.3 super(type, obj) -> bound super object
3.4 super(type, type2) -> bound super object
其他文章:
Python 面向对象编程 OOP--01--类和实例的基本概念
Python 面向对象编程 OOP--02--类中的单下划线和双下划线 5 种情况
Python 面向对象编程 OOP--03--类的组合和派生
Python 面向对象编程 OOP--04--多重继承和方法解释顺序 MRO
Python 面向对象编程 OOP 05--类、实例和其他对象的内建函数
前面的 Python 面向对象编程 OOP 5 小节中,可能都提到过类、子类、继承和派生等概念,几乎处处可以见到 super() 的身影,很多时候它被当作函数在用,但是其实它是一个类!
Python 面向对象编程 OOP--01--类和实例的基本概念Python 面向对象编程 OOP--02--类中的单下划线和双下划线 5 种情况
Python 面向对象编程 OOP--03--类的组合和派生
Python 面向对象编程 OOP--04--多重继承和方法解释顺序 MRO
Python 面向对象编程 OOP--05--类、实例和其他对象的内建函数
1. 描述器 Descriptor
1.1 描述器的定义
根据 python 的定义,类只要实现了__get__, __set__和__delete__中的一个或多个,就认为是一个描述器。
1.1.1 函数是一个描述器
万物都是对象,函数也不例外。当我们使用 def 定义一个函数的时候,相当于创建一个函数对象。因为函数实现了__call__方法,所以可以被调用。
即使是一个空函数,也实现了 '__get__',可以认为是一个描述器。
1.2 描述器的功能
描述器这个类,可以通过__get__, __set__, __delete__方法分别控制属性的访问、赋值和删除操作,当某个类定义了一个描述器对象的类属性,调用这个类对象的此属性,会触发相应描述器的__get__, __set__, __delete__方法。它是@property、super、静态方法、类方法、甚至属性、实例背后的实现机制,是一种比较底层的设计。
2. super() 是一个描述器类,不是一个函数!
super() 是一个描述器类,不是一个函数!调用 super() 会创建一个super对象.
使用 help(super) 获得以下信息
Help on class super in module builtins: class super(object) | super() -> same as super(__class__, <first argument>) | super(type) -> unbound super object | super(type, obj) -> bound super object; requires isinstance(obj, type) | super(type, type2) -> bound super object; requires issubclass(type2, type) | Typical use to call a cooperative superclass method: | class C(B): | def meth(self, arg): | super().meth(arg) | This works for class methods too: | class C(B): | @classmethod | def cmeth(cls, arg): | super().cmeth(arg) | | Methods defined here: | | __get__(self, instance, owner, /) | Return an attribute of instance, which is of type owner. | | __getattribute__(self, name, /) | Return getattr(self, name). | | __init__(self, /, *args, **kwargs) | Initialize self. See help(type(self)) for accurate signature. | | __repr__(self, /) | Return repr(self). | | ---------------------------------------------------------------------- | Static methods defined here: | | __new__(*args, **kwargs) from builtins.type | Create and return a new object. See help(type) for accurate signature. | | ---------------------------------------------------------------------- | Data descriptors defined here: | | __self__ | the instance invoking super(); may be None | | __self_class__ | the type of the instance invoking super(); may be None | | __thisclass__ | the class invoking super()
3. super() 语法
super() 有 4 种典型用法。
3.1 super() 相当于 super(__class__, <first argument>)
super() 是 python3 中支持的写法,是一种调用上的优化,其实相当于第一个参数传入调用super 的当前的类,第二个参数传入调用 super 的方法的第一个参数。
3.2 super(type) : 创建一个未绑定 super 对象
创建一个未绑定 super 对象(unbound)
这时候要查找父类的某个方法时候,就是按照 MRO 列表 依次查询。
3.3 super(type, obj) -> bound super object
需要绑定一个类和对象,且这个对象和类的关系是 isinstance(obj, type) 为 True。
super(type, obj).classfunc 是个’method’,即视作类方法,obj作为X.classfunc的第一个 self 参数自动传入(隐式传入)。Python 会在 inst 的类的 MRO 列表上搜索 type 的下一个类。
3.4 super(type, type2) -> bound super object
首先,要求这两个类的关系是 issubclass(type2, type) 为 True。
其次,MRO 指的是 type2 的 MRO,MRO 中肯定含有一个类就是 type,然后从 type 后面的类开始查找 。也就是说,查找方式时不是像常规方法一样从所有的 MRO 类中查找
举例子, 有个 MRO:[A, B, C, D, E, object]
下面的调用:super(C, A).add(),super 只会从 C 之后查找,即: 只会在 D 或 E 或 object 中查找 add 方法
4. super() 好处
1) 减少了反复写父类的名称,也减少了父类名称修改后的代码量
2) super 机制里可以保证公共父类仅被执行一次,至于执行的顺序,是按照 MRO(Method Resolution Order):方法解析顺序进行的。