Py_InitializeEx进行python的初始化工作。多数东西都不懂,简单记录一下,备忘。
进程状态
首先创建:
-
进程状态PyInterpreterState对象 interp
-
线程状态PyThreadState对象 tstate
当前线程状态对象存于一个static变量中,可以通过PyThreadState_Get()获取。通过线程状态对象进而可以获取进程状态对象。
-
interp->modules 保存所有模块
-
interp->sysdict 对应sys模块的md_dict
-
interp->builtins 对应builtins模块的md_dict
typedef struct _is {
struct _is *next;
struct _ts *tstate_head;
PyObject *modules;
PyObject *modules_by_index;
PyObject *sysdict;
PyObject *builtins;
PyObject *modules_reloading;
PyObject *codec_search_path;
PyObject *codec_search_cache;
PyObject *codec_error_registry;
int codecs_initialized;
int fscodec_initialized;
int dlopenflags;
int tscdump;
} PyInterpreterState;
builtins模块
buildtins模块中:
内置类型
SETBUILTIN("None", Py_None);
SETBUILTIN("Ellipsis", Py_Ellipsis);
SETBUILTIN("NotImplemented", Py_NotImplemented);
SETBUILTIN("False", Py_False);
SETBUILTIN("True", Py_True);
SETBUILTIN("bool", &PyBool_Type);
SETBUILTIN("memoryview", &PyMemoryView_Type);
SETBUILTIN("bytearray", &PyByteArray_Type);
SETBUILTIN("bytes", &PyBytes_Type);
SETBUILTIN("classmethod", &PyClassMethod_Type);
...
以及内置函数
{"__import__", (PyCFunction)builtin___import__, METH_VARARGS | METH_KEYWORDS, import_doc},
{"abs", builtin_abs, METH_O, abs_doc},
{"all", builtin_all, METH_O, all_doc},
{"any", builtin_any, METH_O, any_doc},
{"ascii", builtin_ascii, METH_O, ascii_doc},
{"bin", builtin_bin, METH_O, bin_doc},
{"callable", builtin_callable, METH_O, callable_doc},
{"chr", builtin_chr, METH_VARARGS, chr_doc},
...
设置模块搜索路径
PySys_SetPath(Py_GetPath());设置模块的搜索路径,即:sys.path
重点在 Py_GetPath()
wchar_t *
Py_GetPath(void)
{
if (!module_search_path)
calculate_path();
return module_search_path;
}
如果已经使用Py_SetPath()设置了搜索路径,将返回该路径;
否则,将按照默认规则查找路径(见 Modules/getpath.c 中的注释)。
__main__模块
初始化__main__模块,并将 builtins 模块以名字__builtins__加入:
static void
initmain(void)
{
PyObject *m, *d;
m = PyImport_AddModule("__main__");
d = PyModule_GetDict(m);
if (PyDict_GetItemString(d, "__builtins__") == NULL) {
PyObject *bimod = PyImport_ImportModule("builtins");
PyDict_SetItemString(d, "__builtins__", bimod);
Py_DECREF(bimod);
}
}
恩,有些晕,看两行代码:
>>> __name__ '__main__' >>> __builtins__.__name__ 'builtins'
site.py
通过 initsite() 来初始化第三方模块的路径,它是通过导入site.py 模块实现的。
- 将site-packages 路径加入到 sys.path
- 处理site-packages路径下的xx.pth文件,将其指定的路径加入到 sys.path
| module | pure Python module |
| extension module | |
| package | 包含有__init__.py的文件夹 |
| root package | 不含__init__.py的文件夹,需要加入sys.path |
Py_InitializeEx源码
| void | |
| Py_InitializeEx(intinstall_sigs) | |
| { | |
| PyInterpreterState*interp; | 指针:进程状态、线程状态、内置模块、sys模块、标准出错 |
| PyThreadState*tstate; | |
| PyObject*bimod,*sysmod,*pstderr; | |
| if(initialized) | 标记是否已经初始化,可以使用 Py_IsInitialized()获取 |
| return; | |
| initialized=1; | |
| interp=PyInterpreterState_New(); | 创建进程状态、线程状态对象。当前线程状态存于全局变量 _PyThreadState_Current,可通过PyThreadState_Get()等获取 |
| tstate=PyThreadState_New(interp); | |
| (void)PyThreadState_Swap(tstate); | |
| _PyEval_FiniThreads(); | 多线程环境初始化 |
| _PyGILState_Init(interp,tstate); | |
| _Py_ReadyTypes(); | 内置类型等 初始化 |
| _PyFrame_Init(); | |
| _PyLong_Init(); | |
| PyByteArray_Init(); | |
| _PyFloat_Init(); | |
| _PyUnicode_Init(); | |
| interp->modules=PyDict_New(); | 将保存所有的模块对象到变量interp->modules |
| interp->modules_reloading=PyDict_New(); | |
| bimod=_PyBuiltin_Init(); | builtins模块的初始化,其md_dict存入interp->builtins |
| _PyImport_FixupBuiltin(bimod,"builtins"); | |
| interp->builtins=PyModule_GetDict(bimod); | |
| Py_INCREF(interp->builtins); | |
| _PyExc_Init(); | 内置异常初始化 |
| sysmod=_PySys_Init(); | sys模块的初始化,其md_dict存入interp->sysdict |
| interp->sysdict=PyModule_GetDict(sysmod); | |
| Py_INCREF(interp->sysdict); | |
| _PyImport_FixupBuiltin(sysmod,"sys"); | |
| PySys_SetPath(Py_GetPath()); | 设置module的搜索路径 |
| PyDict_SetItemString(interp->sysdict,"modules", | |
| interp->modules); | |
| pstderr=PyFile_NewStdPrinter(fileno(stderr)); | 标准出错 |
| PySys_SetObject("stderr",pstderr); | |
| PySys_SetObject("__stderr__",pstderr); | |
| Py_DECREF(pstderr); | |
| _PyImport_Init(); | |
| _PyImportHooks_Init(); | |
| _PyWarnings_Init(); | |
| _PyTime_Init(); | |
| initfsencoding(interp); | |
| initsigs(); | |
| initmain();/*Module__main__*/ | 初始化__main__模块 |
| initstdio(); | |
| initsite();/*Modulesite*/ | 初始化site模块的路径 |
| } |
参考
- Python源码剖析,陈儒

2291

被折叠的 条评论
为什么被折叠?



