一、Python中的对象
Python中一切皆是对象。
————Guido van Rossum(1989)
这句话只要你学过python,你就很有可能在你的Python学习之旅的前30分钟就已经见过了,但是这句话具体是什么意思呢?
一句话来说,就是面向对象中的“类”和“对象”在Python中都是对象。类似于int对象的类型对象,实现了“类的概念”,对类型对象“实例化”得到的实例对象实现了“对象”这个概念。
通常的说法是,对象是数据以及基于这些数据的操作的集合。在计算机上,一个对象实际上就是一片被分配的内存空间,这些内存可能是连续的,也有可能是离散的,这都不重要,重要的是这片内存在更高的层次上可以作为一个整体来考虑,这个整体就是一个对象。在这片内存中,存储着一系列的数据以及可以对这些数据进行修改或读取的一系列操作的代码。
在 Python 中,对象就是在堆上申请的结构体,对象不能是被静态初始化的,并且也不能是在栈空间上生存的。唯一的例外就是类型对象(type object),本文来源gao($daima.com搞@代@#码8网^Python中所有的类型对象都是被静态初始化的。在 Python 中,一个对象一旦被创建,它在内存中的大小就是不变的了。 这就意味着那些需要容纳可变长度数据的对象只能在对象内维护一个指向一个可变大小的内存区域的指针。
1.1 对象机制的基石PyObject
PyObject
和 PyVarObject
分别表示定长对象和变长对象,使用的C的struct
实现的,在结构中分别只定义了 PyObject_HEAD
和 PyObject_VAR_HEAD
,后者仅仅是前者加上一个表示容纳元素个数的ob_size
。
[object.h] /* PyObject_HEAD defines the initial segment of every PyObject. */ #define PyObject_HEAD \ _PyObject_HEAD_EXTRA \ int ob_refcnt; \ struct _typeobject *ob_type; #define PyObject_VAR_HEAD \ PyObject_HEAD \ int ob_size; /* Number of items in variable part */
而对于两者共有的PyObject_HEAD
中,只有两个东西,一个是维护引用计数的ob_refcnt
和一个指向类型对象PyTypeObject
结构体的指针。因此, Python 中实际上对象机制的核心非常的简单,一个是引用计数,一个就是类型。并且Python中每一个对象的开始字节都是相同的头部,这使得对Python对象的引用十分统一,只需要一个PyObject*
可以引用任意一个对象。
这两个结构体定义的只是Python中对象共有的部分,其他的具体类型会有额外的结构体来定义,否则的话所有的对象岂不是都一样了?比如int类型的结构体定义PyIntObject
中包含了PyObject_HEAD
和ob_ival
后者是一个long,存放具体的值。
二、类型对象
那初始化对象的时候,去那里获得对象的大小呢?只能是在类型对象PyTypeObject
中了!类型对象中存放了大量对象的元信息,大小显然是一种和对象的类型有关的元信息!注意,一个PyObject对象就是Python中对面向对象理论中类这个概念的实现,这里面存放了类型名、内存空间、操作函数指针等信息。
2.1 对象的创建
Python会用两种方法创建对象,一种是泛型API(AOL:Abstract Object Layer),可以应用在任何Python对象上,API内不会有机制确定最终调用哪个具体函数,比如PyObject_New(PyObject, &PyInt_Type)
。另一种是类型相关API(COL:Concrete Object Layer),只能应用于具体类型的对象上,比如PyInt_FromLong(10)
。