对于一段Python代码,其对应的PyCodeObject对象只有一个,而代码所对应的PyFunctionObject对象却可能有很多个,比如一个函数多次调用,则Python会在运行时创建多个PyFunctionObject对象,
我对这个说法表示怀疑,从源码来看,在def一个函数的时候,会执行MAKE_FUNCTION创建一个PyFunctionObject,而在调用的时候,只是执行CALL_FUNCTION,以PyFunctionObject为基础,产生一个PyFrameObject而开始执行。此期间没有看到PyFunctionObject的复制或新建。奇怪。除非所指的是内嵌函数,在外层函数多次调用时,会产生多个内嵌函数的PyFunctionObject,他们带有同一个PyCodeObject。但这种情况下,实际上是执行了多次def,而不是多次对内嵌函数的调用。
书里讲的仅仅是2.2 new-class的MRO顺序策略,老旧了。实际上,python存在三种策略:一种是针对classic对象的策略,简单深搜。一种是在2.2中针对new-class的策略,如书中所讲。一种是在2.3及以后针对new-class的策略,名为C3算法。可参考http://python-history./2010/06/method-resolution-order.html
descriptor,加上decorator语法,就更千变万化了。
在2.6.8版本的代码中,Python/import.c#2207 get_parent函数。在__name__和__path__之前,先会监测__package__属性,如果已有了,就直接使用。
if ((pkgname != NULL) && (pkgname != Py_None)) {
/* __package__ is set, so use it */
Py_ssize_t len;
if (!PyString_Check(pkgname)) {
PyErr_SetString(PyExc_ValueError,
"__package__ set to non-string");
return NULL;
}
len = PyString_GET_SIZE(pkgname);
if (len == 0) {
if (level > 0) {
PyErr_SetString(PyExc_ValueError,
"Attempted relative import in non-package");
return NULL;
}
return Py_None;
}
if (len > MAXPATHLEN) {
PyErr_SetString(PyExc_ValueError,
"Package name too long");
return NULL;
}
strcpy(buf, PyString_AS_STRING(pkgname));
} else {
/* __package__ not set, so figure it out and set it */
关于GIL的争论:An open letter to Guido van Rossum http://blog./?p=94
It isn't Easy to Remove the GIL http://www./weblogs/viewpost.jsp?thread=214235GIL介绍:Inside the Python GIL http://www./python/GIL.pdf
Inside the New Python GIL http://www./python/NewGIL.pdf (针对3.2新的GIL策略)其他解决途径:2.6引进的multiprocessing标准库,方便多进程编程。C/C++扩展ctypes
书中所说,t_bootstrap调用PyThreadState_New,继而调用_PyGILState_NoteThreadState。在2.6.8版本代码中,t_bootstrap转为调用_PyThreadState_Init,继而调用_PyGILState_NoteThreadState。PyThreadState_New中不再负责_PyGILState_NoteThreadState。
Python的arena从不释放pool。
这句话说的不是很准确,机制上,一个usable的arena就是拥有64个pool空间,不会向系统释放单独释放某个或某些pool。应当说是arena_object释放arena占用的空间(实际包括所有的pool),从usable变成unused。犹如http://bugs./issue1123430中Time Peters所说:Python's small-object allocator now returns an arena to the system.
不归还Int和Float缓冲区内存的问题已在2.6解决。http://docs./whatsnew/2.6.html
To reduce memory usage, the garbage collector will now clear internal free lists when garbage-collecting the highest generation of objects. This may return memory to the operating system sooner.Several basic data types, such as integers and strings, maintain internal free lists of objects that can be re-used. The data structures for these free lists now follow a naming convention: the variable is always named free_list, the counter is always named numfree, and a macro Py<typename>_MAXFREELIST is always defined.