paramètre passé à __str__ [résolu]

paramètre passé à __str__ [résolu] - Python - Programmation

Marsh Posté le 13-09-2010 à 23:25:29    

Bonsoir, je travaille avec Python 3 mais le problème se pose aussi avec une version classique (2.6.1 par exemple).
je pose une question qui me titille; soit une classe dont la fonction __str__ accepte un argument (disons, par exemple, un int) :
 

Code :
  1. class C(object):
  2.     def __str__(self,arg):
  3.         return "(objet C)"+str(arg)


J'ai un problème de compréhension sur l'appel de C.__str__; le code suivant fonctionne parfaitement :

Code :
  1. c = C()
  2. print( c.__str__(3) )


mais pas celui-ci :

Code :
  1. c = C()
  2. print( str(c,3) )


 
avec Python 3.2a j'ai droit à l'erreur :  

Code :
  1. TypeError: str() argument 2 must be str, not int


 
avec Python 2.6.1, pour le même code, j'ai en erreur :

Code :
  1. TypeError: str() takes at most 1 argument (2 given)


 
Voyez-vous pourquoi je dois passer par l'écriture c.__str__ que je trouve lourde ? Merci de m'aider !

Message cité 1 fois
Message édité par suizokukan le 14-09-2010 à 09:21:47

---------------
rule #1 : trust the python
Reply

Marsh Posté le 13-09-2010 à 23:25:29   

Reply

Marsh Posté le 14-09-2010 à 00:15:57    

Je reponds surtout pour python 2.6
 
Si tu appeles directement la fonction __str__ (http://docs.python.org/reference/d [...] ct.__str__), c'est comme si tu appelais une fonction classique, donc c'est normal que cela fonctionne.
 
Par contre la fonction str ne prend qu'un seul argument http://docs.python.org/library/functions.html#str, d'ou le message d'erreur.
 
Apres, la fonctionne __str__ est la pour retourner une chaine de charactere representant l'objet, je ne vois donc pas trop l'interet qu'elle ait des arguments. Je pense qu'il serait mieux d'appeler ta fonction autrement, et de l'appeler classiquement.


Message édité par mr simon le 14-09-2010 à 00:17:12
Reply

Marsh Posté le 14-09-2010 à 03:02:52    

Dans la doc de Python 3.1 , je vois:

Citation :

str([object[, encoding[, errors]]])
(...) The encoding parameter is a string giving the name of an encoding;


Comme dans str(c,3) l’argument 3 n’est pas une string, ça coince.
 
 
Dans Python 2.x, str() n’a qu’un seul paramètre:

Citation :

str([object])
Return a string containing a nicely printable representation of an object.


str(c,3) est donc incorrect
 
 
 
 
 
 
 
D’autre part , il faut bien distinguer les deux écritures c.__str__(3) et str(c,3) et comprendre ce qu’il se passe dans la première.
 
 
 
Étant donné ta définition de def __str__(self,arg) avec un paramètre arg,
tu peux écrire l’instruction c.__str__(3) si ça te chante, parce que, dans cette instruction, c.__str__ est une méthode
et qu’à partir de là, l’interpréteur Python transforme cette instruction en l’instruction C.__str__(c,3) dans laquelle C.__str__ est une fonction qui a bien 2 paramètres. En effet:

Citation :


the special thing about methods is that the object is passed as the first argument of the function.  
http://docs.python.org/release/3.1 [...] at-classes


 
Donc, écrire c.__str__(3) c’est comme si tu écrivais C.__str__(c,3) dans laquelle __str__ est une fonction à deux paramètres, et comme l’a écrit mr simon, c’est un appel banal de fonction à deux paramètres. Ça prend un chemin à rallonge avant d’y arriver, mais c’est ça.
 
 
 
 
 
 
Par ailleurs, il est prévu de façon tout à fait aussi fondamentale dans le langage, que la fonction __str__() attribut d’un objet O est appelée chaque fois que l’instruction str(O) est effectuée:
 
c’est à dire que str(O) déclenche O.__str()__ , et en vertu de la même transformation que ci-dessus, c’est finalement type(O).__str__(O) qui est exécutée.
 
Cependant, que je sache, cette disposition n’est prévue que pour une écriture str(O) , pas une écriture à deux paramètres telle que str(c,3).
 
 
 
 
 
 
Ceci étant, tu as donc un problème puisque tu souhaites, si j’ai bien compris, obtenir l’affichage de (objet C)3 en appelant la fonction __str__ de la classe C avec l’argument 3 juste après une instatiation c = C().
 
Si ça ne marche pas, c’est que ce n’est pas la bonne manière de faire. À mon avis, il faut, non pas que le 3 soit spécifié à partir de l’extérieur en le passant comme argument à la fonction __str__ de la classe C , mais en faisant en sorte que cette fonction le trouve disponible dans l’instance. Il faut pour cela que la valeur 3 soit définie dans l’instance au moment de l’instanciation, et cela relève d’une fonction __init__ :
 

Code :
  1. class C(object):
  2.     def __init__(self):
  3.         self.arg = 3
  4.     def __str__(self):
  5.         return "(objet C)"+str(self.arg)


 
 
 
 
 
 
 
Mais je crois que ceci n’est encore pas exactement ce que tu veux.
 
Je pense que tu voudrais que arg contienne le numéro d’ordre de l’instance de C concernée, c’est à dire un nombre qui traduise quel est la position d’un objet dans la suite des objets obtenus par instanciations successives de C.
 
Et ce doit donc être ceci que tu souhaites:

Code :
  1. class C(object):
  2.     arg = -1
  3.     def __str__(self):
  4.         C.arg += 1
  5.         return "(objet C)"+str(C.arg)
  6. a = C()
  7. print( 'a :  '+str(a) )
  8. b = C()
  9. print( 'b :  '+str(b) )
  10. c = C()
  11. print( 'c :  '+str(c) )
  12. a = C()
  13. print( 'a :  '+str(a) )


 
Résultat:
 

Code :
  1. a :  (objet C)0
  2. b :  (objet C)1
  3. c :  (objet C)2
  4. a :  (objet C)3


 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Reply

Marsh Posté le 14-09-2010 à 09:21:05    

> eyquem, mr simon : merci infiniment pour vos réponses : je ne connaissais pas assez bien les spécifications de str dans Python 2/3
> eyquem : merci pour ta longue analyse de la question; ton idée sur ce que représente l'int <arg> passé à ma fonction str n'a rien à voir avec l'usage que j'en veux faire. Néanmoins, ton code est très intéressant à lire !
 
Merci beaucoup !


---------------
rule #1 : trust the python
Reply

Marsh Posté le 14-09-2010 à 09:56:32    

suizokukan a écrit :

Bonsoir, je travaille avec Python 3 mais le problème se pose aussi avec une version classique (2.6.1 par exemple).
je pose une question qui me titille; soit une classe dont la fonction __str__ accepte un argument (disons, par exemple, un int)


La méthode __str__ n'a pas à accepter de paramètres autres que self. Problème clos.


Message édité par masklinn le 14-09-2010 à 09:56:56

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 14-09-2010 à 09:58:45    

eyquem a écrit :

Je pense que tu voudrais que arg contienne le numéro d’ordre de l’instance de C concernée, c’est à dire un nombre qui traduise quel est la position d’un objet dans la suite des objets obtenus par instanciations successives de C.
 
Et ce doit donc être ceci que tu souhaites:

Code :
  1. class C(object):
  2.    arg = -1
  3.    def __str__(self):
  4.        C.arg += 1
  5.        return "(objet C)"+str(C.arg)
  6.  
  7. a = C()
  8. print( 'a :  '+str(a) )
  9. b = C()
  10. print( 'b :  '+str(b) )
  11. c = C()
  12. print( 'c :  '+str(c) )
  13. a = C()
  14. print( 'a :  '+str(a) )


 
Résultat:
 

Code :
  1. a :  (objet C)0
  2. b :  (objet C)1
  3. c :  (objet C)2
  4. a :  (objet C)3




>>> class C(object):
...     arg = -1
...     def __str__(self):
...         C.arg += 1
...         return "(objet C)"+str(C.arg)
...  
>>> a = C()
>>> str(a)
'(objet C)0'
>>> str(a)
'(objet C)1'
>>> str(a)
'(objet C)2'
>>> str(a)
'(objet C)3'
>>> str(a)
'(objet C)4'


[:petrus75]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 15-09-2010 à 11:07:57    

Bien vu, Masklinn. Où avais-je la tête ?
 
Ça se règle facilement:
 

Code :
  1. class C(object):
  2.     n = -1
  3.     def __init__(cap):
  4.         C.n += 1
  5.         cap.arg = C.n # numéro d'ordre de création de l'instance
  6.     def __str__(self): 
  7.         return "(objet C)"+str(self.arg)
  8. a = C()
  9. print str(a)
  10. print str(a)
  11. print str(a)
  12. print str(a)
  13. print str(a)


Code :
  1. (objet C)0
  2. (objet C)0
  3. (objet C)0
  4. (objet C)0
  5. (objet C)0


 
 
 
 
 
Mais il m’a pris de sophistiquer les choses:
 
- j’ai voulu que quand une instance disparait, les numéros d’ordre de toutes les autres instances créées postérieurement à celle qui disparait diminuent de 1.
 
Ce n’est pas facile à cause du fait que si des alias ont été définis sur une instance, la décrémentation ne doit se faire que si un del détruit le dernier nom alias de l’instance.
 
J’ai pensé que j’y arriverais grâce à la fonction __del__() qui n’est appelée que quand un objet va disparaitre par élimination de la dernière référence pointant sur lui. Mais je ne sais pourquoi, lorsque j’arrivais à l’élimination de la dernière référence que j’avais définie dans un programme pour une instance donnée, le getrefcount() sur l’instance concernée ne donnait pas 1 (ni même 2, pour ceux qui sont au courant d’un truc particulier avec getrefcount() ) mais beaucoup plus.
 
J’ai alors essayé d’y arriver en faisant des calculs sur les refcounts d’une instance. Mais échec aussi.
 
 
Finalement, je me suis résous à détruire les instances seulement en passant par une méthode delete() créée spécialement dans chaque instance pour controler les délétions de noms.
 
Ceci s’est accompagné de la nécessité que les aliasing ne se fassent pas par b = a mais pas une méthode spécialement destinée à faire cela : a.aliasing(’b’) crée un alias b sur l’instance de nom a.
Je ne suis pas arrivé à faire autrement là aussi, je rencontrais des problèmes trop importants en essayant de m’en passer.
 
 
 
Si quelqu’un arrive à obtenir les mêmes résultats que moi sans ces deux méthodes dédiées, je lui tirerai mon chapeau.
 
 
 
 
- dans la foulée, comme j’avais de toutes façons besoin d’un compteur du nombre de noms pour chaque instance, j’ai fait afficher ce renseignement aussi par l’appel de __str__()
On peut suivre dans l’exemple qui suit le code ci-après les variations du nombre de noms pour chaque instance concernée par une modification (en couleur).
 
 
 
 

Code :
  1. class C(object):
  2.     n = -1          # numéro de création de la précédente instance
  3.     inst = set([])  # ensemble cumulatif des instances créées
  4.    
  5.     def __init__(cap):
  6.         # Fixation du numéro d'ordre d’une instance à sa création:
  7.         C.n += 1
  8.         cap.numero = C.n
  9.         # Création du compteur de noms de l'instance:
  10.         cap.cnt_noms = 1
  11.         # Enregistrement de l'instance créée et affichage du suivi du déroulement:
  12.         C.inst.add(cap)
  13.         print 'Ensemble C.inst apres initialisation :\n  '+\
  14.               ' , '.join(repr(y)[-11:-5]+'~'+repr(y)[-5:-1] for y in C.inst)
  15.        
  16.     def __str__(self):
  17.         return "(objet C)%i  repéré par %i nom%s"\
  18.                % (self.numero, self.cnt_noms, (self.cnt_noms>1)*'s')
  19.        
  20.     def aliasing(self,ch):
  21.         globals()[ch] = self
  22.         self.cnt_noms += 1
  23.     def delete(self,ci):
  24.         if self.cnt_noms==1: # il ne reste plus qu'une référence sur self, donc:
  25.             # - on élimine tout ce qui concerne l'instance concernée self
  26.             self.__class__.n -= 1
  27.             self.__class__.inst.remove(self)
  28.             # - on décrémente les numéros d'ordre des instances créées après self
  29.             for instance in self.__class__.inst:
  30.                     instance.numero -= instance.numero>self.numero
  31.         del globals()[ci]
  32.         self.cnt_noms -= 1
  33.         print 'Ensemble C.inst après DEL :\n  '+\
  34.               ' , '.join(repr(y)[-11:-5]+'~'+repr(y)[-5:-1] for y in C.inst)
  35.    
  36. class D:
  37.     pass
  38. classes_utilisateur =(C,D)
  39. print 'a = C()'
  40. a = C()
  41. print 'str(a) :  '+str(a)
  42. print 'a      : ',a
  43. print '\nb = C()'
  44. b = C()
  45. print 'str(a) :  '+str(a)
  46. print 'a      : ',a
  47. print 'str(b) :  '+str(b)
  48. print 'b      : ',b
  49. print '\nc = C()'
  50. c = C()
  51. print 'a :  '+str(a)
  52. print 'b :  '+str(b)
  53. print 'c :  '+str(c)
  54. print '\nd = C()'
  55. d = C()
  56. print 'a :  '+str(a)
  57. print 'b :  '+str(b)
  58. print 'c :  '+str(c)
  59. print 'd :  '+str(d)
  60. print '\ne = C()'
  61. e = C()
  62. print 'a :  '+str(a)
  63. print 'b :  '+str(b)
  64. print 'c :  '+str(c)
  65. print 'd :  '+str(d)
  66. print 'e :  '+str(e)
  67. print "\nc.aliasing('f')"
  68. c.aliasing('f')
  69. print 'a :  '+str(a)
  70. print 'b :  '+str(b)
  71. print 'c :  '+str(c)
  72. print 'd :  '+str(d)
  73. print 'e :  '+str(e)
  74. print 'f :  '+str(f)
  75. print "\ng = C()"
  76. g = C()
  77. print 'a :  '+str(a)
  78. print 'b :  '+str(b)
  79. print 'c :  '+str(c)
  80. print 'd :  '+str(d)
  81. print 'e :  '+str(e)
  82. print 'f :  '+str(f)
  83. print 'g :  '+str(g)
  84. print "\nf.aliasing('h')"
  85. f.aliasing('h')
  86. print 'a :  '+str(a)
  87. print 'b :  '+str(b)
  88. print 'c :  '+str(c)
  89. print 'd :  '+str(d)
  90. print 'e :  '+str(e)
  91. print 'f :  '+str(f)
  92. print 'g :  '+str(g)
  93. print 'h :  '+str(h)
  94. print "\nf.delete('f')"
  95. f.delete('f')
  96. print 'a :  '+str(a)
  97. print 'b :  '+str(b)
  98. print 'c :  '+str(c)
  99. print 'd :  '+str(d)
  100. print 'e :  '+str(e)
  101. try:  print 'f :  '+str(f)
  102. except:  print 'f :              identifiant detruit'
  103. print 'g :  '+str(g)
  104. print 'h :  '+str(h)
  105. print "\nb.aliasing('i')"
  106. b.aliasing('i')
  107. print 'a :  '+str(a)
  108. print 'b :  '+str(b)
  109. print 'c :  '+str(c)
  110. print 'd :  '+str(d)
  111. print 'e :  '+str(e)
  112. try:  print 'f :  '+str(f)
  113. except:  print 'f :              identifiant detruit'
  114. print 'g :  '+str(g)
  115. print 'h :  '+str(h)
  116. print 'i :  '+str(i)
  117. print "\nc.delete('c')"
  118. c.delete('c')
  119. print 'a :  '+str(a)
  120. print 'b :  '+str(b)
  121. try:  print 'c :  '+str(c)
  122. except:  print 'c :              identifiant detruit'
  123. print 'd :  '+str(d)
  124. print 'e :  '+str(e)
  125. try:  print 'f :  '+str(f)
  126. except:  print 'f :              identifiant detruit'
  127. print 'g :  '+str(g)
  128. print 'h :  '+str(h)
  129. print 'i :  '+str(i)
  130. print '\nj = C()'
  131. j = C()
  132. print 'a :  '+str(a)
  133. print 'b :  '+str(b)
  134. try:  print 'c :  '+str(c)
  135. except:  print 'c :              identifiant detruit'
  136. print 'd :  '+str(d)
  137. print 'e :  '+str(e)
  138. try:  print 'f :  '+str(f)
  139. except:  print 'f :              identifiant detruit'
  140. print 'g :  '+str(g)
  141. print 'h :  '+str(h)
  142. print 'i :  '+str(i)
  143. print 'j :  '+str(j)
  144. print "\nh.delete('h')"
  145. h.delete('h')
  146. print 'a :  '+str(a)
  147. print 'b :  '+str(b)
  148. try:  print 'c :  '+str(c)
  149. except:  print 'c :              identifiant detruit'
  150. print 'd :  '+str(d)
  151. print 'e :  '+str(e)
  152. try:  print 'f :  '+str(f)
  153. except:  print 'f :              identifiant detruit'
  154. print 'g :  '+str(g)
  155. try:  print 'h :  '+str(h)
  156. except:  print 'h :              identifiant detruit'
  157. print 'i :  '+str(i)
  158. print 'j :  '+str(j)
  159. print "\na.delete('a')"
  160. a.delete('a')
  161. try:  print 'a :  '+str(a)
  162. except:  print 'a :              identifiant detruit'
  163. print 'b :  '+str(b)
  164. try:  print 'c :  '+str(c)
  165. except:  print 'c :              identifiant detruit'
  166. print 'd :  '+str(d)
  167. print 'e :  '+str(e)
  168. try:  print 'f :  '+str(f)
  169. except:  print 'f :              identifiant detruit'
  170. print 'g :  '+str(g)
  171. try:  print 'h :  '+str(h)
  172. except:  print 'h :              identifiant detruit'
  173. print 'i :  '+str(i)
  174. print 'j :  '+str(j)


 
 

Code :
  1. a = C()
  2. Ensemble C.inst apres initialisation :
  3.   0x0109~EDB0
  4. str(a) :  (objet C)0  repéré par 1 nom
  5. a      :  (objet C)0  repéré par 1 nom
  6. b = C()
  7. Ensemble C.inst apres initialisation :
  8.   0x0109~ED90 , 0x0109~EDB0
  9. str(a) :  (objet C)0  repéré par 1 nom
  10. a      :  (objet C)0  repéré par 1 nom
  11. str(b) :  (objet C)1  repéré par 1 nom
  12. b      :  (objet C)1  repéré par 1 nom
  13. c = C()
  14. Ensemble C.inst apres initialisation :
  15.   0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
  16. a :  (objet C)0  repéré par 1 nom
  17. b :  (objet C)1  repéré par 1 nom
  18. c :  (objet C)2  repéré par 1 nom
  19. d = C()
  20. Ensemble C.inst apres initialisation :
  21.   0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0 , 0x010B~7AB0
  22. a :  (objet C)0  repéré par 1 nom
  23. b :  (objet C)1  repéré par 1 nom
  24. c :  (objet C)2  repéré par 1 nom
  25. d :  (objet C)3  repéré par 1 nom
  26. e = C()
  27. Ensemble C.inst apres initialisation :
  28.   0x0109~ED90 , 0x0109~EDB0 , 0x010B~7B10 , 0x00AD~05D0 , 0x010B~7AB0
  29. a :  (objet C)0  repéré par 1 nom
  30. b :  (objet C)1  repéré par 1 nom
  31. c :  (objet C)2  repéré par 1 nom
  32. d :  (objet C)3  repéré par 1 nom
  33. e :  (objet C)4  repéré par 1 nom
  34. c.aliasing('f')
  35. a :  (objet C)0  repéré par 1 nom
  36. b :  (objet C)1  repéré par 1 nom
  37. c :  (objet C)2  repéré par 2 noms
  38. d :  (objet C)3  repéré par 1 nom
  39. e :  (objet C)4  repéré par 1 nom
  40. f :  (objet C)2  repéré par 2 noms
  41. g = C()
  42. Ensemble C.inst apres initialisation :
  43.   0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
  44. a :  (objet C)0  repéré par 1 nom
  45. b :  (objet C)1  repéré par 1 nom
  46. c :  (objet C)2  repéré par 2 noms
  47. d :  (objet C)3  repéré par 1 nom
  48. e :  (objet C)4  repéré par 1 nom
  49. f :  (objet C)2  repéré par 2 noms
  50. g :  (objet C)5  repéré par 1 nom
  51. f.aliasing('h')
  52. a :  (objet C)0  repéré par 1 nom
  53. b :  (objet C)1  repéré par 1 nom
  54. c :  (objet C)2  repéré par 3 noms
  55. d :  (objet C)3  repéré par 1 nom
  56. e :  (objet C)4  repéré par 1 nom
  57. f :  (objet C)2  repéré par 3 noms
  58. g :  (objet C)5  repéré par 1 nom
  59. h :  (objet C)2  repéré par 3 noms
  60. f.delete('f')
  61. Ensemble C.inst après DEL :
  62.   0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
  63. a :  (objet C)0  repéré par 1 nom
  64. b :  (objet C)1  repéré par 1 nom
  65. c :  (objet C)2  repéré par 2 noms
  66. d :  (objet C)3  repéré par 1 nom
  67. e :  (objet C)4  repéré par 1 nom
  68. f :              identifiant detruit
  69. g :  (objet C)5  repéré par 1 nom
  70. h:  (objet C)2  repéré par 2 noms
  71. b.aliasing('i')
  72. a :  (objet C)0  repéré par 1 nom
  73. b :  (objet C)1  repéré par 2 noms
  74. c :  (objet C)2  repéré par 2 noms
  75. d :  (objet C)3  repéré par 1 nom
  76. e :  (objet C)4  repéré par 1 nom
  77. f :              identifiant detruit
  78. g :  (objet C)5  repéré par 1 nom
  79. h :  (objet C)2  repéré par 2 noms
  80. i :  (objet C)1  repéré par 2 noms
  81. c.delete('c')
  82. Ensemble C.inst après DEL :
  83.   0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
  84. a :  (objet C)0  repéré par 1 nom
  85. b :  (objet C)1  repéré par 2 noms
  86. c :              identifiant detruit
  87. d :  (objet C)3  repéré par 1 nom
  88. e :  (objet C)4  repéré par 1 nom
  89. f :              identifiant detruit
  90. g :  (objet C)5  repéré par 1 nom
  91. h :  (objet C)2  repéré par 1 nom
  92. i :  (objet C)1  repéré par 2 noms
  93. j = C()
  94. Ensemble C.inst apres initialisation :
  95.   0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x010B~7B30 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
  96. a :  (objet C)0  repéré par 1 nom
  97. b :  (objet C)1  repéré par 2 noms
  98. c :              identifiant detruit
  99. d :  (objet C)3  repéré par 1 nom
  100. e :  (objet C)4  repéré par 1 nom
  101. f :              identifiant detruit
  102. g :  (objet C)5  repéré par 1 nom
  103. h :  (objet C)2  repéré par 1 nom
  104. i :  (objet C)1  repéré par 2 noms
  105. j :  (objet C)6  repéré par 1 nom
  106. h.delete('h')
  107. Ensemble C.inst après DEL :
  108.   0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x010B~7B30 , 0x0109~ED90 , 0x0109~EDB0
  109. a :  (objet C)0  repéré par 1 nom
  110. b :  (objet C)1  repéré par 2 noms
  111. c :              identifiant detruit
  112. d :  (objet C)2  repéré par 1 nom
  113. e :  (objet C)3  repéré par 1 nom
  114. f :              identifiant detruit
  115. g :  (objet C)4  repéré par 1 nom
  116. h :              identifiant detruit
  117. i :  (objet C)1  repéré par 2 noms
  118. j :  (objet C)5  repéré par 1 nom
  119. a.delete('a')
  120. Ensemble C.inst après DEL :
  121.   0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x010B~7B30 , 0x0109~ED90
  122. a :              identifiant detruit
  123. b :  (objet C)0  repéré par 2 noms
  124. c :              identifiant detruit
  125. d :  (objet C)1  repéré par 1 nom
  126. e :  (objet C)2  repéré par 1 nom
  127. f :              identifiant detruit
  128. g :  (objet C)3  repéré par 1 nom
  129. h :              identifiant detruit
  130. i :  (objet C)0  repéré par 2 noms
  131. j :  (objet C)4  repéré par 1 nom


 
 
 


Message édité par eyquem le 15-09-2010 à 11:15:43
Reply

Marsh Posté le 15-09-2010 à 11:48:10    

Non mais weakref quoi :/


Message édité par masklinn le 15-09-2010 à 11:48:35

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 16-09-2010 à 17:01:30    

Le code que j’ai donné dans mon précédent message effectue ceci:
 

Code :
  1. class C:
  2.     pass
  3. # soit une classe C
  4. a = C()
  5. # crée une instance UNE de C, de numéro d’ordre 0.
  6. b = a
  7. c = a
  8. d = b
  9. # ajoutent trois alias du nom a sur cette instance.


L’instance UNE est donc repérée par 4 noms.
 

Code :
  1. k = C()
  2. # crée une deuxième instance DEUX de C, de numéro d’ordre 1.
  3. m = k
  4. # ajoute un alias sur cette instance


Cette instance DEUX est alors repérée par deux noms.
 
 
Si maintenant je fais del c, il disparait une référence sur l’instance de numéro 0, mais il en reste 3 qui gardent l’instance en vie.
Puis del b, il en reste 2.
Puis del a, il en reste 1, et l’instance est toujours conservée en vie, même si c’est le premier nom (a) sous lequel l’instance a été créée qui vient d’être détruit.
 
Pour atteindre l’extinction de l’instance, il faut enfin faire del d.
À ce moment là, mon code fait passer le numéro d’ordre de l’autre instance , DEUX, créée postérieurement à l’instance UNE qui vient de disparaitre, de 1 à 0.
 
 
 
 
 
 
Ceci étant, si je définissais b , c , d comme des références faibles:

Code :
  1. b = weakref.ref(a)
  2. c = weakref.ref(a)
  3. d = weakref.ref(a)


il se passerait que l’instance UNE disparaitrait dès que serait exécutée del a. Un tel algorithme n’est pas celui dans lequel on n’obtient la destruction de l’instance UNE que lorsque tous les noms qui lui ont été associés ont été détruits.
 
J’ai écrit ce dernier algorithme sans qu’il ait été demandé , par amusement.  
Masklin, si ta remarque est destinée à me donner l’idée d’un autre algorithme, je veux bien. Je peux effectivement en faire un autre...
 
Mais ce que j’aurais aimé, c’est trouver un moyen de faire tel que les événements ci-dessus décrits soit exécutés par un programme dans lequel les délétions ne se feraient pas par f.delete(’f’) , mais par l’instruction de base del f.
 
Si ta remarque sous-entend qu’on peut y arriver en utilisant les weakrefs, tu devrais en dire plus car je ne vois pas en quoi les weakrefs apporteraient une solution à mon problèm. Sinon elle tape à coté de ce que je souhaite quoi.
 

Reply

Marsh Posté le 16-09-2010 à 19:40:07    

eyquem a écrit :

Mais ce que j’aurais aimé, c’est trouver un moyen de faire tel que les événements ci-dessus décrits soit exécutés par un programme dans lequel les délétions ne se feraient pas par f.delete(’f’) , mais par l’instruction de base del f.


Je sais pas ce que tu veux, tes posts c'est un foutoir illisible de 3km avec du gras et des espaces partout au hazard, on dirait du jovalise sous extas. Tout ce que je peux te dire, c'est que si l'idée te venait un jour de lire la doc de weakref, tu trouverais probablement l'argument callback à weakref.ref et weakref.proxy qui est appelé quand l'objet derrière disparaît. Mais surtout si tu regardais ce que fait weakref tu te rendrais compte que tu peux l'utiliser pour garder une liste de toutes tes instances et que ça évite d'écrire les tartines que tu balourdes depuis 3 posts avec ton bordel de delete() à appeler manuellement pour pouvoir décrémenter un refcount pourri qui vient de ton utilisation de vraies références là où t'en as absolument pas besoin.

 

Somme toute, ton problème n'existe que parce que tu l'as crée toi même sans aucune raison externe de le faire.


Message édité par masklinn le 16-09-2010 à 19:41:18

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed