我注意到有关CPython的对象释放的一些事情引起了我的好奇心.假设我定义了一个从其tp_dealloc
函数中打印消息的类型:
static void pyfoo_Bar_dealloc(pyfoo_Bar* self) { PySys_WriteStdout("Bar freed\n"); self->ob_type->tp_free((PyObject*)self); }
我也用分配器做了正确的事情:
PyMODINIT_FUNC initpyfoo(void) { PyObject* m; pyfoo_BarType.tp_new = PyType_GenericNew; /* ... */ }
我编译它并在目录中运行Python 2.6解释器pyfoo.so
:
>>> import pyfoo >>> a = pyfoo.Bar() >>> a = None Bar freed >>> quit()
这就是我所期望的......引用计数降为零并Bar
收集对象.但现在如果我这样做:
>>> import pyfoo >>> pyfoo.Bar()>>> quit() Bar freed
...在Bar
解释器退出之前,不会收集对象.但是,Bar
匿名创建的对象的引用计数肯定是零,就像显式分配的那样.那么为什么它在创作后不会立即解除分配?
(我在Debian Squeeze上用Python 2.6.6编译了GCC 4.4.5.我知道这不是一个"bug",我知道Python-the-language并没有对Python解释器施加任何特殊限制.我只是想知道引擎盖下发生了什么,使它忽略了这样的匿名对象.)
因为在您调用pyfoo.Bar()
对象后仍可使用特殊对象访问_
这适用于纯Python,顺便说一下:
class X: def __del__(self): print 'deleted'
然后:
>>>a = X() >>>a = None deleted >>>X() <__main__.X instance at 0x7f391bb066c8> >>> _ <__main__.X instance at 0x7f391bb066c8> >>> 3 # causes _ to be reassigned deleted 3
请注意如何重新分配_
隐式删除X
对象?