Python原始碼學習 之 Python直譯器

2021-08-26 02:10:23 字數 3403 閱讀 5539

include/

公有 標頭檔案

lib/

python編寫的模組

modules/

c實現的模組

objects/

內建物件型別的實現

pc/windows下構建python的工程檔案

pcbuild/

parser/

直譯器的 parser、tokenizer、input handling

python/

直譯器的 byte-compiler、interpreter

configure

shell 指令碼

...在windows下:pcbuild 下是vs2008 的工程檔案

在linux下:

./configure

make

sudo make install

python 直譯器(可執行程式) 本身的**非常簡單,就是呼叫了 py_main 這個函式!

python2.7

python3.2

int py_main(int argc, char **argv)

int py_main(int argc, wchar_t **argv)

pymain

pyrun_anyfileexflags

pyrun_interactiveloopflags

pyrun_interactiveoneflags

pyparser_parsefileflag***

pyast_compile

pyeval_evalcode

pyrun_******fileexflags

pyparser_astfromfile

pyast_compile

pyeval_evalcode

呼叫主要有兩個分支

二者最終都是

三個步驟。

在python2中,使用的窄字串,在python3中,使用寬字串。所以python3的原始碼乍看起來複雜了好多。

原始碼:modules/python.c

#include "python.h"

intmain(int argc, char **argv)

#include "python.h"

#include

#ifdef ms_windows

intwmain(int argc, wchar_t **argv)

#else

intmain(int argc, char **argv)

#endif

在 windows 下,由於鏈結子系統和入口函式問題,所以有乙個單獨的 pythonw.exe :原始碼 pc/winmain.c

#include "python.h"

#define win32_lean_and_mean

#include

int winapi wwinmain(

hinstance hinstance, /* handle to current instance */

hinstance hprevinstance, /* handle to previous instance */

lpwstr lpcmdline, /* pointer to command line */

int ncmdshow /* show state of window */

)

python2中與此幾乎完全相同,用__argv取代__wargv

原始碼定義在 modules/main.c

int

py_main(int argc, wchar_t **argv)

else if (module)

else

... if (sts == -1)

sts = run_file(fp, filename, &cf);

}... if (py_inspectflag && stdin_is_interactive &&

(filename != null || command != null || module != null))

... py_finalize();

...}

呼叫py_finalize();

原始碼:python/pythonrun.c

/* parse input from a file and execute it */

intpyrun_anyfileexflags(file *fp, const char *filename, int closeit,

pycompilerflags *flags)

else

return pyrun_******fileexflags(fp, filename, closeit, flags);

}

兩個分支:

下面3個馬甲都是直接呼叫的該函式:

pyrun_anyfile(file *fp, const char *name)

pyrun_anyfileex(file *fp, const char *name, int closeit)

pyrun_anyfileflags(file *fp, const char *name, pycompilerflags *flags)

前面分流的兩個分支,最後又都會呼叫 run_mod 函式

static pyobject *

run_mod(mod_ty mod, const char *filename, pyobject *globals, pyobject *locals,

pycompilerflags *flags, pyarena *arena)

簡單看看 python -c "print('hello')" 這種命令列語句會發生什麼?

首先從 py_main 看起,

int

py_main(int argc, wchar_t **argv)

... }

... if (command != null)

... if (command)

...}

static int

run_command(wchar_t *command, pycompilerflags *cf)

這兒呼叫的pyrun_******stringflags將會呼叫pyrun_stringflags進而將呼叫 run_mod,這又回到了前面所看到的**。

Python原始碼學習 之bytecode

原始碼 py檔案 或 字串 位元組碼 可快取在 pyc 結果 pythonx.dll libpythonx.x.a pythonx.dll libpythonx.x.a py compilestring pyeval eval compile eval 中通過import使用到的.py檔案會自動編譯...

Python原始碼學習 之模組路徑

接前面python原始碼筆記之py initializeex,嘗試看看python中用到的一些path 這部分東西太亂了.具體見pc getpathp.c 和 modules getpath.c 中的注釋 乙個python程式要有執行,必須要能找到 py pyc pyo pyd so 等,如何找到這...

原始碼學習之IntenteService

intentservice是基於service實現的,它會按需求處理一些非同步任務。通過呼叫startservice,客戶端就可以傳送請求了。如果有需要的話,service才會被啟動,在子執行緒依次處理每個intent,處理完任務以後service會停止。使用的時候要繼承intentservice,...