`
tomhibolu
  • 浏览: 1411633 次
文章分类
社区版块
存档分类
最新评论

[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源码剖析,陈儒

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics