首页 > 代码库 > 《python源码剖析》笔记 python环境初始化

《python源码剖析》笔记 python环境初始化

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie


1.线程环境初始化

Py_InitializeEx,Python会首先调用 PyInterpreterState_New创建一个崭新的PyInterpreterState对象。

创建了PyInterpreterState(进程状态)对象之后,Python会调用PyThreadState_New创建PyThreadState(线程状态)对象

全局变量_PyThreadState_Current维护着当前活动的线程
PyInterpreterState对象中维护着所有的PyThreadState对象共享的资源


2.系统module初始化
Python最终会将interp->modules创建为一个PyDictObject对象,它维护着系统所有的(module名,module对象)的对应关系
创建__builtin__ module

PyObject *
_PyBuiltin_Init(void)
{
    PyObject *mod, *dict, *debug;
	//[1]:创建并设置__builtin__ module
    mod = Py_InitModule4("__builtin__", builtin_methods,
                         builtin_doc, (PyObject *)NULL,
                         PYTHON_API_VERSION);
    //[2]:将所有Pyton内建类型加入到__builtin__ module中
    dict = PyModule_GetDict(mod);


#define SETBUILTIN(NAME, OBJECT)     if (PyDict_SetItemString(dict, NAME, (PyObject *)OBJECT) < 0)               return NULL;                                                        


    SETBUILTIN("None",                  Py_None);
    SETBUILTIN("Ellipsis",              Py_Ellipsis);
    SETBUILTIN("NotImplemented",        Py_NotImplemented);
    SETBUILTIN("False",                 Py_False);
    SETBUILTIN("True",                  Py_True);
    SETBUILTIN("basestring",            &PyBaseString_Type);
    SETBUILTIN("bool",                  &PyBool_Type);
    SETBUILTIN("memoryview",        &PyMemoryView_Type);
    SETBUILTIN("bytearray",             &PyByteArray_Type);
    SETBUILTIN("bytes",                 &PyString_Type);
    SETBUILTIN("buffer",                &PyBuffer_Type);
    SETBUILTIN("classmethod",           &PyClassMethod_Type);
#ifndef WITHOUT_COMPLEX
    SETBUILTIN("complex",               &PyComplex_Type);
#endif
    SETBUILTIN("dict",                  &PyDict_Type);
    SETBUILTIN("enumerate",             &PyEnum_Type);
    SETBUILTIN("file",                  &PyFile_Type);
    SETBUILTIN("float",                 &PyFloat_Type);
    SETBUILTIN("frozenset",             &PyFrozenSet_Type);
    SETBUILTIN("property",              &PyProperty_Type);
    SETBUILTIN("int",                   &PyInt_Type);
    SETBUILTIN("list",                  &PyList_Type);
    SETBUILTIN("long",                  &PyLong_Type);
    SETBUILTIN("object",                &PyBaseObject_Type);
    SETBUILTIN("reversed",              &PyReversed_Type);
    SETBUILTIN("set",                   &PySet_Type);
    SETBUILTIN("slice",                 &PySlice_Type);
    SETBUILTIN("staticmethod",          &PyStaticMethod_Type);
    SETBUILTIN("str",                   &PyString_Type);
    SETBUILTIN("super",                 &PySuper_Type);
    SETBUILTIN("tuple",                 &PyTuple_Type);
    SETBUILTIN("type",                  &PyType_Type);
    SETBUILTIN("xrange",                &PyRange_Type);
#ifdef Py_USING_UNICODE
    SETBUILTIN("unicode",               &PyUnicode_Type);
#endif
  

    return mod;
#undef SETBUILTIN
}
static PyMethodDef builtin_methods[] = {
    {"__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},
    {"apply",           builtin_apply,      METH_VARARGS, apply_doc},
    {"bin",             builtin_bin,        METH_O, bin_doc},
    {"callable",        builtin_callable,   METH_O, callable_doc},
    {"chr",             builtin_chr,        METH_VARARGS, chr_doc},
    {"cmp",             builtin_cmp,        METH_VARARGS, cmp_doc},
    {"coerce",          builtin_coerce,     METH_VARARGS, coerce_doc},
    {"compile",         (PyCFunction)builtin_compile,    METH_VARARGS | METH_KEYWORDS, compile_doc},
    {"delattr",         builtin_delattr,    METH_VARARGS, delattr_doc},
    {"dir",             builtin_dir,        METH_VARARGS, dir_doc},
    {"divmod",          builtin_divmod,     METH_VARARGS, divmod_doc},
    {"eval",            builtin_eval,       METH_VARARGS, eval_doc},
    {"execfile",        builtin_execfile,   METH_VARARGS, execfile_doc},
    {"filter",          builtin_filter,     METH_VARARGS, filter_doc},
    {"format",          builtin_format,     METH_VARARGS, format_doc},
    {"getattr",         builtin_getattr,    METH_VARARGS, getattr_doc},
    {"globals",         (PyCFunction)builtin_globals,    METH_NOARGS, globals_doc},
    {"hasattr",         builtin_hasattr,    METH_VARARGS, hasattr_doc},
    {"hash",            builtin_hash,       METH_O, hash_doc},
    {"hex",             builtin_hex,        METH_O, hex_doc},
    {"id",              builtin_id,         METH_O, id_doc},
    {"input",           builtin_input,      METH_VARARGS, input_doc},
    {"intern",          builtin_intern,     METH_VARARGS, intern_doc},
    {"isinstance",  builtin_isinstance, METH_VARARGS, isinstance_doc},
    {"issubclass",  builtin_issubclass, METH_VARARGS, issubclass_doc},
    {"iter",            builtin_iter,       METH_VARARGS, iter_doc},
    {"len",             builtin_len,        METH_O, len_doc},
    {"locals",          (PyCFunction)builtin_locals,     METH_NOARGS, locals_doc},
    {"map",             builtin_map,        METH_VARARGS, map_doc},
    {"max",             (PyCFunction)builtin_max,        METH_VARARGS | METH_KEYWORDS, max_doc},
    {"min",             (PyCFunction)builtin_min,        METH_VARARGS | METH_KEYWORDS, min_doc},
    {"next",            builtin_next,       METH_VARARGS, next_doc},
    {"oct",             builtin_oct,        METH_O, oct_doc},
    {"open",            (PyCFunction)builtin_open,       METH_VARARGS | METH_KEYWORDS, open_doc},
    {"ord",             builtin_ord,        METH_O, ord_doc},
    {"pow",             builtin_pow,        METH_VARARGS, pow_doc},
    {"print",           (PyCFunction)builtin_print,      METH_VARARGS | METH_KEYWORDS, print_doc},
    {"range",           builtin_range,      METH_VARARGS, range_doc},
    {"raw_input",       builtin_raw_input,  METH_VARARGS, raw_input_doc},
    {"reduce",          builtin_reduce,     METH_VARARGS, reduce_doc},
    {"reload",          builtin_reload,     METH_O, reload_doc},
    {"repr",            builtin_repr,       METH_O, repr_doc},
    {"round",           (PyCFunction)builtin_round,      METH_VARARGS | METH_KEYWORDS, round_doc},
    {"setattr",         builtin_setattr,    METH_VARARGS, setattr_doc},
    {"sorted",          (PyCFunction)builtin_sorted,     METH_VARARGS | METH_KEYWORDS, sorted_doc},
    {"sum",             builtin_sum,        METH_VARARGS, sum_doc},
#ifdef Py_USING_UNICODE
    {"unichr",          builtin_unichr,     METH_VARARGS, unichr_doc},
#endif
    {"vars",            builtin_vars,       METH_VARARGS, vars_doc},
    {"zip",         builtin_zip,        METH_VARARGS, zip_doc},
    {NULL,              NULL},
};


创建sys module
Python在创建并设置了__builtin__ module之后,会用同样的流程设置sys module,并像设置
interp->builtins一样设置interp->sysdict


创建__main__ module
static void
initmain(void)
{
    PyObject *m, *d;
	//[1]:创建 __main__ module,并将其插入 interp-modules中
    m = PyImport_AddModule("__main__");
    //[2]:获得 __main__ module 中的dict
    d = PyModule_GetDict(m);
    if (PyDict_GetItemString(d, "__builtins__") == NULL) {
		//[3]:获得interp->modules中的 __builtin__ module
        PyObject *bimod = PyImport_ImportModule("__builtin__");
		//[4]:将("__builtin__", __builtin__ module) 插入到 __main__ module 的dict中
        PyDict_SetItemString(d, "__builtins__", bimod);   
    }
}

单元测试
if __name__ == "__main__"

设置site-specific的module的搜索路径
site.py
1.将site-packages路径加入到sys.path中
2.将site-packages目录下的所有.pth文件中的所有路径加入到sys.path中


3.激活Python虚拟机
先编译Python语句获得抽象语法树
再获得<module __main__>中维护的dict作为当前活动的frame对象的local名字空间 global名字空间
交互方式运行和脚本文件方式运行最终都会进行run_mode函数,然后启动虚拟机 
static PyObject *
run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
         PyCompilerFlags *flags, PyArena *arena)
{
    PyCodeObject *co;
    PyObject *v;
	//[1]:基于AST编译字节码指令序列,创建PyCodeObject对象
    co = PyAST_Compile(mod, filename, flags, arena);
    //[2]:创建PyFrameObject对象,执行PyCodeObject对象中的字节码指令序列
	v = PyEval_EvalCode(co, globals, locals);
    Py_DECREF(co);
    return v;
}

创建PyCodeObject对象--> PyEval_EvalCode执行PyCodeObject对象中的字节码-->创建PyFrameObject-->PyEval_EvalFrameEx在PyFrameObject上下文环境中执行PyCodeObject对的字节码

名字空间
PyFrameObject *
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
            PyObject *locals)
{
    PyFrameObject *back = tstate->frame;
    PyFrameObject *f;
    PyObject *builtins;
    Py_ssize_t i;
	
	//[1]:设置builtin名字空间
    if (back == NULL || back->f_globals != globals) {
        builtins = PyDict_GetItem(globals, builtin_object);
    }
    else {
        builtins = back->f_builtins;
    }
    f->f_builtins = builtins;
    f->f_back = back;
	
	//[2]:设置global名字空间
    f->f_globals = globals;
    
	//[3]:设置local名字空间
	if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) ==
        (CO_NEWLOCALS | CO_OPTIMIZED))
        ; /* f_locals = NULL; will be set by PyFrame_FastToLocals() */
    else if (code->co_flags & CO_NEWLOCALS) {
        locals = PyDict_New();
        f->f_locals = locals;
    }
    else {
        if (locals == NULL)
            locals = globals;//一般情况下,locals和globals指向形同的dict
    }
    return f;
}

Python所有的线程都共享同样的builtin名字空间
在激活Python字节码虚拟机时,local名字空间和global名字空间一样都被设置成了 __main__ module中的dict