levée d'exception et compteur de références
Bonjour
j'obtiens un comportement que je trouve bizarre lors de la levée d'une exception dans une méthode de classe : l'appelant se retrouve avec une instance qui a un compteur de référence différent de 1 (un peu comme si, lors de la remontée des fonctions/méthodes jusqu'à trouver un traitement pour l'exception, le compteur de référence restait inchangé).
Du coup, au niveau de l'appelant, un "del" de l'instance ne fait que décrémenter ce compteur sans que la méthode __del__ que j'ai définie soit exécutée.
La classe (simplifiée !) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from sys import getrefcount as grc
class Classe(object):
def ooops(self):
print "debut ooops :", grc(self)
raise RuntimeError('exception provoquee')
def methode(self,exception=False):
print "debut methode :", grc(self)
if exception: self.ooops()
print "fin methode :", grc(self)
def __del__(self):
print "destructeur appelee :", grc(self)
print "ici des choses a faire" |
A l'usage, sans levée d'exception :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| plx@sony:~/Bureau$ py
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from grc_v1 import Classe
>>> from sys import getrefcount as grc
>>> i=Classe()
>>> grc(i)
2
>>> i.methode()
debut methode : 4
fin methode : 4
>>> grc(i)
2
>>> del i
destructeur appelee : 5
ici des choses a faire |
quand une exception est levée :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| plx@sony:~/Bureau$ py
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from grc_v1 import Classe
>>> from sys import getrefcount as grc
>>> i=Classe()
>>> grc(i)
2
>>> i.methode(True)
debut methode : 4
debut ooops : 6
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "grc_v1.py", line 11, in methode
if exception: self.ooops()
File "grc_v1.py", line 7, in ooops
raise RuntimeError('exception provoquee')
RuntimeError: exception provoquee
>>> grc(i)
4
>>> del i
>>> del i
destructeur appelee : 5
ici des choses a faire
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
>>> |
(le deuxième "del i" n'est évidemment pas licite mais les messages retournés sont intéressants)
Par contre, dans le méthode "methode", si je traite l'exception, au final, au niveau de l'appelant, l'instance a un compteur qui vaut 1 et un del provoque bien l'exécution de la méthode __del__ :
Code:
1 2 3 4 5 6 7 8
| def methode(self,exception=False):
print "debut methode :", grc(self)
if exception:
try:
self.ooops()
except:
print "ooops a leve une exception"
print "fin methode :", grc(self |
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from grc_v2 import Classe
>>> from sys import getrefcount as grc
>>> i=Classe()
>>> grc(i)
2
>>> i.methode(True)
debut methode : 4
debut ooops : 6
ooops a leve une exception
fin methode : 5
>>> grc(i)
2
>>> del i
destructeur appelee : 5
ici des choses a faire
>>> |
Je trouve ça choquant. Qu'en pensez-vous ? Ai-je loupé quelque chose ?
ps : j'ai strictement la même chose en version 2.7