2010-11-09 2 views
4

J'ai remarqué quelque chose à propos de la désallocation d'objet de CPython qui a piqué ma curiosité. Disons que je définir un type qui imprime un message de sa fonction tp_dealloc:Pourquoi les objets Python anonymes (C) ne sont-ils pas désaffectés immédiatement?

static void pyfoo_Bar_dealloc(pyfoo_Bar* self) 
{  
    PySys_WriteStdout("Bar freed\n"); 
    self->ob_type->tp_free((PyObject*)self); 
} 

J'ai aussi fait la bonne chose avec l'allocateur:

PyMODINIT_FUNC initpyfoo(void) 
{ 
    PyObject* m; 

    pyfoo_BarType.tp_new = PyType_GenericNew; 
    /* ... */ 
} 

Je le compiler et exécuter un interpréteur Python 2.6 dans le répertoire avec pyfoo.so:

>>> import pyfoo 
>>> a = pyfoo.Bar() 
>>> a = None 
Bar freed 
>>> quit() 

C'est ce que je pense ... le compte de référence tombe à zéro et l'objet Bar est collecté . Mais si je fais:

>>> import pyfoo 
>>> pyfoo.Bar() 
<pyfoo.Bar object at 0x7f7c6d8f2080> 
>>> quit() 
Bar freed 

... l'objet Bar n'est pas recueilli jusqu'à ce que les sorties d'un interprète. Mais sûrement le compte de référence sur l'objet Bar créé de manière anonyme est nul, tout comme celui explicitement assigné. Alors pourquoi n'est-il pas désaffecté immédiatement après la création?

(Je le fais sur Debian Squeeze avec Python 2.6.6 compilé avec GCC 4.4.5 Je sais que ce n'est pas un "bug", je sais que Python-the-language ne place aucune contrainte particulière sur Python interprètes ceci ... Je veux juste savoir ce qui se passe sous le capot qui fait qu'il ignore les objets anonymes comme celui-ci.)

Répondre

8

Parce qu'après que vous avez appelé pyfoo.Bar() l'objet est toujours accessible en utilisant l'objet spécial _

Cela fonctionne avec Python pur, en passant:

class X: 
    def __del__(self): 
     print 'deleted' 

Et plus tard:

>>>a = X() 
>>>a = None 
deleted 
>>>X() 
<__main__.X instance at 0x7f391bb066c8> 
>>> _ 
<__main__.X instance at 0x7f391bb066c8> 
>>> 3 # causes _ to be reassigned 
deleted 
3 

Remarquez comment la réaffectation _ a implicitement supprimé l'objet X?

+1

Aha! Bonne réponse, merci. Maintenant, je vois que si je viens d'écrire un script qui l'instancie anonymement et attend avant de quitter, il est en effet GCed immédiatement. – detly

+0

Désolé de draguer à nouveau, mais savez-vous si une chose similaire se produit avec l'exception générée le plus récemment? – detly

+0

C'est le cas; alors que tous les gestionnaires d'exceptions pertinents sont en cours d'exécution, l'exception est disponible en tant que membre de sys.exc_info(), et je me souviens vaguement qu'il est stocké ailleurs après que le gestionnaire ait fini de fonctionner même si je ne suis pas sûr à 100%. – javawizard

3

Parce que vous utilisez le REPL, qui stocke le dernier résultat dans _. Donc ce n'est pas vraiment après tout.

Questions connexes