Decode

programming blog by huangsunyang


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

CPython Super

发表于 2020-04-21 更新于 2020-04-22 分类于 python源码
本文字数: 2.1k 阅读时长 ≈ 10 分钟

什么是super

super实际上就是抽象的父类对象,用面向对象的方式来调用父类方法的一层封装。典型的使用方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Base(object):
def __init__(self):
pass

@classmethod
def test(cls):
pass

class Derived(Base):
def __init__(self):
super(Derived, self).__init__() # (1)
# super().__init__() # python3
# Base.__init__(self) # 非面向对象

@classmethod
def test(cls):
super(Derived, cls).test() # (3)
# super().test() # python3

super的四种用法

根据super的文档,其一共有三种用法:

  • super(type, obj) -> bound super object; requires isinstance(obj, type)
  • super(type) -> unbound super object
  • super(type, type2) ->bound super object; requires issubclass(type2, type)

其中,第二种用法相对少见。除此之外,在python3中,可以使用无参数的super。

super的实现

super在实现上是一个内置类型,定义在typeobject.c中,其结构体定义如下:

1
2
3
4
5
6
typedef struct {
PyObject_HEAD
PyTypeObject *type; // __thisclass__ the class invoking super
PyObject *obj; // __self__ the instance invoking super
PyTypeObject *obj_type; // __self_class__ the type of __self__
} superobject;

简单来说,super实现的是一层封装,将对super对象的函数调用转发到对应的父类中去。父类的寻找遵循python中的mro顺序。

super对象的创建

super对象的创建相对比较简单,只是将第第一个参数赋值给type,第二个参数赋值给obj,通过调用supercheck进行类型检查,并计算出第三个参数的值。规律如下:

  • obj是类型且obj需要是type的子类,则obj_type等于obj
  • obj的类型是type的子类,则obj_type等于Py_TYPE(obj)
  • obj.__class__是type的子类,则obj_type等于obj.__class__

super对象获取父类数据

从super对象中获取数据用的是super_getattro函数,各种情况如下:

  • 如果obj_type为NULL,则直接从当前super对象中获取数据,通常是出错的情况
  • 如果获取的是__class__属性,则也从当前super对象获取
  • 从obj_type.__mro__中找到type,从这一项之后开始遍历,从中找到第一个类(新式类/旧式类),从中寻找该变量并返回。如果变量是一个descriptor,则尝试调用其tp_descr_get方法。
  • 如果寻找失败,则从当前super对象中获取数据

python3中的super

python3中的super能够省略参数,其具体实现是从当前栈帧中寻找第一个参数作为obj,从闭包中寻找__class__作为type。后者的实现细节较为复杂,甚至可以说比较混乱:

  • 在语法分析阶段,如果使用了super关键字,就会隐式地将__class__加入到符号表
  • drop_class_free中将判断__class__是否在局部变量中,如果存在,将其删除并标记ste_needs_class_closure
  • 编译阶段通过ste_needs_class_closure标志位判断将其隐式加入到类的cellvars中

参考资料

  1. https://stackoverflow.com/questions/36993577/schr%C3%B6dingers-variable-the-class-cell-magically-appears-if-youre-checking
  2. https://www.artima.com/weblogs/viewpost.jsp?thread=281127
# python # 源码 # cpython # python-objects
LR(k) Parser
CPython Memory Management
  • 文章目录
  • 站点概览
_huang

_huang

12 日志
5 分类
18 标签
GitHub E-Mail
  1. 1. 什么是super
  2. 2. super的四种用法
  3. 3. super的实现
    1. 3.1. super对象的创建
    2. 3.2. super对象获取父类数据
  4. 4. python3中的super
  5. 5. 参考资料
© 2020 _huang | 59k | 4:53
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Muse v7.3.0