J'ai une classe qui ouvre un fichier pour écrire. Dans mon destructeur, j'appelle la fonction qui ferme le fichier: mais lorsque je supprime l'objet avec le code comme: p> si J'essaie de réintégrer l'objet, j'obtiens une erreur de valeur: p> alors que si j'appelle myobj.close () code> avant
del myobj code> Je ne reçois pas ce problème. Alors pourquoi n'est-il pas
__ del __ () code> être appelé? P> p>
4 Réponses :
Ce n'est pas ce que La différence courte est qu'il est facile de garantir quand un destructeur est appelé, mais vous avez très peu de garanties sur lorsque Si vous voulez un scopage lexical, utilisez un J'ai trouvé une autre réponse ( lien ) à une question différente qui répond à cela plus en détail. Il est regrettable que la réponse acceptée à cette question contienne des erreurs flagrantes. P>
edit: strong> Comme notitors noté, vous devez hériter de del code> fait. Il est malheureux que
__ del __ code> a le même nom que
del code>, car ils ne sont pas liés les uns aux autres. Dans la terminologie moderne, la méthode
__ del __ code> serait appelée un em> finaliseur em>, pas un destructeur em> et la différence est importante. P>
__ del __ code> sera appelé et il pourrait jamais em> être appelé . Il existe de nombreuses circonstances différentes pouvant causer cela. p>
avec la relève code>. Sinon, appelez
myobj.close () code> directement. La déclaration
del code> ne supprime que des références, pas des objets. P>
objet code>. C'est bon, mais il est toujours possible que
__ del __ code> ne soit jamais appelé (vous pourriez avoir de la chance). Voir la réponse liée ci-dessus. P>
Êtes-vous sûr de vouloir utiliser Vous pouvez faire myClass a Contexte Manager à la place: P > __ del __ code>? Il y a Problèmes avec
__ del __ code> et collection de déchets .
with MyClass() as myobj:
...
+1 pour mentionner les problèmes. docs.python.org/library/gc.html#gc.grage dit que «des objets qui ont __del __ __ () et font partie d'un cycle de référence car l'ensemble du cycle de référence doit être irréelectable, y compris des objets non nécessairement dans le cycle mais ne sont pas atteints de celui-ci.»
Je ne vois pas comment il y a un cycle de référence dans l'exemple de l'OP. Il y a un objet, il obtient del code> d, et
__ del __ () code> ne s'appelle pas.
De plus, dans ma situation, je préférerais laisser la GC gérer des choses car il n'a pas besoin de se fermer immédiatement, mais cela a finalement ... mais cela a toujours des problèmes. Et non, les gestionnaires de contexte ne sont pas une vraie solution. Ils vous limitent à la fermeture de l'objet dans la même fonction appeler et d'indenter votre code un niveau à chaque fois que vous en utilisez un. Rend ça illisible quand je veux créer 20 d'entre eux.
Votre code doit hériter de Vous pouvez lire sur La version courte de la raison pour laquelle vous devez hériter de Si vous devez compter sur l'appel d'un finaliseur, je suggère fortement que vous utilisiez l'approche du gestionnaire de contexte recommandée dans d'autres réponses, car c'est une solution portable et robuste. P> objet code> - ne le faisant pas a été considéré par date (sauf dans des cas particuliers) pendant au moins six ans. P>
__ del __ code> ici: http: //docs.pytthon.org/reference/datamodel.html#Object. del fort> p>
objet code> est que
__ del __ code> est uniquement "magique" sur des classes de style neuf. P>
Ah vient de trouver une instance où cette "magie" ne fonctionne pas ... en utilisant ipython à la place.
@TDC: À moins que je me trompe, Ipython est basé sur CPPHON. Dans tous les cas, si vous comptez sur le comportement d'une instance particulière, votre code sera non portable. Il serait probablement préférable d'utiliser l'approche du gestionnaire de contexte recommandée dans d'autres réponses.
Peut-être que quelque chose d'autre se réfère, c'est pourquoi Considérez ce code: P> __ del __ code> n'est pas appelé (encore).
#!/usr/bin/env python
import time
class NiceClass():
def __init__(self, num):
print "Make %i" % num
self.num = num
def __del__(self):
print "Unmake %i" % self.num
x = NiceClass(1)
y = NiceClass(2)
z = NiceClass(3)
lst = [x, y, z]
time.sleep(1)
del x
del y
del z
time.sleep(1)
print "Deleting the list."
del lst
time.sleep(1)
Il n'y avait certainement qu'une seule référence dans ce cas
Essayez d'hériter de
objet code> - ne le faisant pas a été considéré comme un style obsolète depuis six ans.
Vous devriez montrer un autre code. Comment peut-on vous dire comment
myobj.close () code> change de choses, sans savoir ce qu'il fait?
N'oubliez pas que
del code> n'appelle pas
__ del __ code>. Cela supprime l'une des références. Généralement, il est préférable de fermer explicitement, éventuellement à l'aide du protocole de Contexte Manager (
avec la déclaration code>).
@Marcin - qui résolva-t-on ... post comme une réponse? Toujours curieux de savoir pourquoi cela devrait être le cas ...