je rapproche d'ailleurs ce problème du manque de destructeur dans les GC dits "modernes" ou "vrais" (java, ruby) avec mark & sweep, par rapport aux GC dits "faux" (perl, python) fonctionnant par compteur de référence ; concrètement il est assez rare d'avoir besoin de destructeurs vrais (c'est à dire qui sont vraiment appelés quand l'objet est déscopé)
Si tu penses que __del__ en Python te garantit d'être appelé lorsque tu sors du "scope" où est défini l'objet, tu te gourres. Rien de tel n'est spécifié, d'ailleurs cela peut être faux selon l'implémentation (par exemple Jython). C'est une erreur courante de penser que __del__ est équivalent aux destructeurs C++.
D'ailleurs, ton souhait n'a un sens que si la notion de "scope" a un sens pour les objets. En Python seuls les noms ont un "scope" alors que les objets vivent indépendamment dans leur monde à eux, quoiqu'ils soient susceptibles d'être détruits quand plus aucun nom ne les réfère directement ou indirectement.
Pire, __del__ peut poser des problèmes avec la destruction de cycle :
>>> class A: pass
...
>>> a = A()
>>> a.a = a
>>> del a
>>> class B:
... def __del__(self): print "hop"
...
>>> b = B()
>>> b.b = b
>>> del b
>>> import gc
>>> gc.garbage
[]
>>> gc.collect()
4 >>> gc.garbage
[<__main__.B instance at 0xb7bed96c>]
[^] # Re: Mes deux centimes ...
Posté par Antoine . En réponse au journal Repenser les langages et le développement logiciel. Évalué à 4.
Si tu penses que __del__ en Python te garantit d'être appelé lorsque tu sors du "scope" où est défini l'objet, tu te gourres. Rien de tel n'est spécifié, d'ailleurs cela peut être faux selon l'implémentation (par exemple Jython). C'est une erreur courante de penser que __del__ est équivalent aux destructeurs C++.
D'ailleurs, ton souhait n'a un sens que si la notion de "scope" a un sens pour les objets. En Python seuls les noms ont un "scope" alors que les objets vivent indépendamment dans leur monde à eux, quoiqu'ils soient susceptibles d'être détruits quand plus aucun nom ne les réfère directement ou indirectement.
Pire, __del__ peut poser des problèmes avec la destruction de cycle :
>>> class A: pass
...
>>> a = A()
>>> a.a = a
>>> del a
>>> class B:
... def __del__(self): print "hop"
...
>>> b = B()
>>> b.b = b
>>> del b
>>> import gc
>>> gc.garbage
[]
>>> gc.collect()
4
>>> gc.garbage
[<__main__.B instance at 0xb7bed96c>]