本文为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