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 !) :
A l'usage, sans levée d'exception :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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"
quand une exception est levée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
(le deuxième "del i" n'est évidemment pas licite mais les messages retournés sont intéressants)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 >>>
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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(selfJe trouve ça choquant. Qu'en pensez-vous ? Ai-je loupé quelque chose ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 >>>
ps : j'ai strictement la même chose en version 2.7
Partager