本篇代碼針對2.X版本,與3.X版本細節不盡相同,由於兩者架構差別不大加之本人能力有限,所以就使用2.X體驗python的底層原理了。
一、主要文件夾內容
Include :該目錄下包含了Python提供的所有頭文件,如果用戶需要自己用C或C++來編寫自定義模塊擴展Python,那么就需要用到這里提供的頭文件。
Lib :該目錄包含了Python自帶的所有標准庫,Lib中的庫都是用Python語言編寫的。
Modules :該文件夾中包含了所有用C語言編寫的模塊,比如ramdom,cStringIO等,Modules中的模塊是那些對速度要求非常嚴格的模塊。而有一些對速度沒有太嚴格要求的模塊,比如os,就是用Python編寫,並且放在Lib目錄下
Parser :Parser目錄中包含了Python解釋器中的Scanner和Parser部分,即對Python源代碼進行詞法分析和語法分析的部分。除了這些,Parser目錄下還包含了一些有用的工具,這些工具能夠根據Python語言的語法自動生成Python語言的詞法和語法分析器,與YACC非常類似。
Objects :該目錄中包含了所有Python的內建對象,包括整數,list,dict等;同時,該目錄還包括了Python在運行時需要的所有的內部使用對象的實現
Python :該目錄下包含了Python解釋器中的Compiler和執行引擎部分,是Python運行的核心所在。
PCBuild :包含了Visual Studio 2003工程文件,研究Python源代碼就從這里開始,實際使用中我使用的是VS 2015。
二、幾個標准函數
1、輸出python對象的接口函數
python/外部依賴項/object.h/
PyAPI_FUNC(int) PyObject_Print(PyObject *, FILE *, int);
2、從C的原生字符數組創建出Python字符串對象
PyObject* str = PyString_FromString("I am in int_print");
3、將Python的整數對象轉化為C中的int型
PyInt_AsLong(v)
4、獲取Python中sys對象(獲取形式采取對象的字符串)
PyObject* out = PySys_GetObject("stdout");
三、修改源碼示意
pythoncore/Objects/intobject.c
/* ARGSUSED */ static int int_print(PyIntObject *v, FILE *fp, int flags) /* flags -- not used but required by interface */ { // add by hellcat if (PyInt_AsLong(v) == -999) { // 將python的int對象轉換為c的整形並做大小判斷 PyObject* str = PyString_FromString("I am in int_print"); // 將c的字符串轉換為python的字符串對象 PyObject* out = PySys_GetObject("stdout"); // 獲取python的sys庫中的stdout屬性 if (out != NULL) { // 如果該屬性存在值 PyObject_Print(out, stdout, 0); // 打印python對象到stdout(屏幕輸出),打印標准輸出的值 printf("\n"); PyObject_Print(str, stdout, 0); // 打印我們之前寫的字符串 printf("\n"); // 打印換行 } } fprintf(fp, "%ld", v->ob_ival); return 0; }
這里的函數int_print是在打印python整形數字時調用,我們設定當打印-999時額外輸出字符串"I am in int_print"。
sys.stdout
介紹一下sys.stdout,如下交互界面輸入,在交互界面不會得到輸出,
import sys sys.stdout = open('123.txt', 'w') sys.stdout
會創建一個123.txt文件,並將所有輸出到命令行的輸出轉而寫進文件。