本系列作为本人@takooctopus深入学习python机制的记录,这个博客遵照着栖迟于一丘的博客上面的流程进行的,也包含我在实际查看源码时的感想,特此列出,表示感谢。
PyObject,对象的基础
PyObject的定义
我们就用官方里面的解释:
没有什么能被完全被声明为一个PyObject
,但每一个指向Python
的对象的指针均能够被视为一个PyObject*
指针。
{{- code -}}
_PyObject_HEAD_EXTRA
再接着我们看里面的第一个属性_PyObject_HEAD_EXTRA
,追踪到
其也定义在object.h里面:
{{- code -}}
其表示我们如果定义了Py_TRACE_REFS
的话,这个结构将可以支持双向列表,并且所有堆中的活动均在这个列表中
因为在 release 下没有定义
Py_TRACE_REFS
,我们可以忽略这个宏
Py_ssize_t
接着我们追踪Py_ssize_t
这个属性
{{- code -}}
关于HAVE_SSIZE_T
查到对于HAVE_SSIZE_T
的默认定义为1,其定义在 pyconfig.h 中
关于ssize_t
即我们默认下,根据平台将ssize_t
的类型设置为__int64
或者_W64
{{- code -}}
关于Py_intptr_t
我们继续看Py_intptr_t
其实是由intptr_t
定义的
{{- code -}}
我们继续看intptr_t
其又在 Include/vcstdint.h 中被定义了:
{{- code -}}
我们看到其在64位系统中是64位的int,而32位系统是_W64,我们可以看到Py_ssize_t
的本质为一个int
此时,我们就可以简化我们所看见的对象了
{{- code -}}
成员作用:
ob_refcnt
:counter,对于变量引用次数进行计数,关于垃圾清理。ob_type
:type,储存了对象的类型信息,如int
,string
,或是function
等
除此之外,这个作为一个基本单元,在实际使用时还需要其他的内容
我们以 PyLongObject 为例:
{{- code -}}
其第一个属性PyObject_VAR_HEAD
由PyVarObject
和ob_base
组成
第二个属性由digit
构成
变长对象和定长对象
在c语言中, 整型占用内存大小是固定的, 无论你保存1还是100. 而由于c没有字符串类型, 因此要表示字符串得用N个char组成数组. 在python中这样描述变长对象:
{{- code -}}
ob_size
表示容纳元素的个数, 不是对象占用的内存字节数.
int | string | list | dict |
---|---|---|---|
ob_refnt | ob_refnt | ob_refnt | ob_refnt |
ob_type | ob_type | ob_type | [others] |
[NULL] | [others] | [others] | [NULL] |
类型对象
{{- code -}}
在 _typeobject
中包含了很多信息,主要有:
- 1.类型名,
tp_name
,格式为 <module>.<name> ,用于内部调用和方便调试 - 2.创建对象时分配内存空间大小的变量,
tp_basicsize
和tp_itemsize
,分别代表基本的大小和里面元素的大小 - 3.与对象相关的操作,如
tp_print
这样的函数 - 4.要描述的本类型的其他信息