我这里使用Python3.5作为学习的源码
|
--- Include: 包括Python提供的所有头文件, 可以用于c/c++扩展
--- Lib: Python的标准库, 全部都是用python写的
--- Modules: 包含了C语言编写的模块, 比如random, StringIO 等
--- Parser: 包含了python解释器中的scanner和parser部分,也就是词法分析和语法分析部分,一个类似yacc一样根据规则自动生成
--- Objects: 包含所有Python的内置对象,整数, list, dict等.也包含了运行时python需要的所有内部使用的对象的实现
--- Python: 包含了python解释器中Compiler和执行引擎部分,是python运行的核心所在
--- PCBuild:包含了vs工程文件
基于C++的调试对于已经到Python虚拟机中存储起来的字节码命令是无法被观察到的,我们只能把它们解析成AST才能看懂字节码在解释器内存中的状态,所以这里我们借用Python解释器里的C_API来输出我们的对象:
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
# eg:
PyObject_Print(v, stdout, 0);
Python的整体架构可分为3个模块
python玩家都知道,在python中,万物皆对象,python的源码中是通过下面的代码去定义每一个对象的。
object.h
typedef struct _object {
_PyObject_HEAD_EXTRA
Py_ssize_t ob_refcnt;
struct _typeobject *ob_type;
} PyObject;
结构体中包含了Py_ssize_t、_typeobject两个成员,下面一个个来看它的成员的定义和意义。
object.h
#ifdef Py_TRACE_REFS
/* Define pointers to support a doubly-linked list of all live heap objects. */
#define _PyObject_HEAD_EXTRA \
struct _object *_ob_next; \
struct _object *_ob_prev;
#define _PyObject_EXTRA_INIT 0, 0,
#else
#define _PyObject_HEAD_EXTRA
#define _PyObject_EXTRA_INIT
#endif
往下检索可以看到定义
pyport.h
typedef Py_intptr_t Py_ssize_t;
pyport.h
typedef intptr_t Py_intptr_t;
vcstdint.h
//预编译判断操作系统类型
#ifdef _WIN64 // [如果是64位操作系统
typedef __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][32位操作系统
typedef _W64 int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
__w64是一个编译器相关的关键字, 意思是说这个类型使用64位兼容方式编译, 在编译64位程序时指针就被视为64位宽, 而不是32位. int也有可能会被视为64位. __int64 原形为
typedef int __w64 __int64
换句话说在64位系统中, 它是64位int整型, 32位系统就是int. _W64 是为了兼容64位系统存在的. 所以 Py_ssize_t 的本质就是 int类型的变量。 将上面的定义全部回带化简以后,代码变成
typedef struct _object {
__int64 ob_refcnt;//int ob_refcnt
struct _typeobject *ob_type;
} PyObject;
表示变量引用次数, python的垃圾回收机制基于引用计数, 在python运行的过程中当某个对象引用计数减少到0时, 就可以将该变量从堆上删除,释放内存。我们可以检索到引用计数的处理定义。
#define Py_INCREF(op) ((op)->ob_refcnt++) //增加计数
#define Py_DECREF(op) \ //减少计数
if (--(op)->ob_refcnt != 0) \
; \
else \
__Py_Dealloc((PyObject *)(op))
引用计数为0时,该对象生命周期结束,python释放内存。
好了到此为止,涉及python的垃圾回收(GC)后面专门会分一篇文章来讲解
表示了对象的类型信息, 诸如int, string, function,class等,这里做一个简述,具体细节留到下一篇python类型对象去写。
(adsbygoogle = window.adsbygoogle || []).push({});