首页 > 代码库 > 《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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。