[Python源码学习]之Py_InitializeEx

来源:互联网 发布:java中什么叫序列化 编辑:程序博客网 时间:2024/06/08 02:26

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 voidinitmain(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(int install_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(); /* Module site */ 

初始化site模块的路径

  } 

 

参考

  • Python源码剖析,陈儒

原创粉丝点击