styxmx 发表于 2017-5-3 07:52:43

[Python源码学习]之Py_InitializeEx

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源码剖析,陈儒
页: [1]
查看完整版本: [Python源码学习]之Py_InitializeEx