您的位置:首页 > 编程语言 > Python开发

[Python源码学习]之Py_InitializeEx

2011-09-12 22:46 836 查看
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(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源码剖析,陈儒
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: