eyquem | Bien vu, Masklinn. Où avais-je la tête ?
Ça se règle facilement:
Code :
- class C(object):
- n = -1
- def __init__(cap):
- C.n += 1
- cap.arg = C.n # numéro d'ordre de création de l'instance
- def __str__(self):
- return "(objet C)"+str(self.arg)
- a = C()
- print str(a)
- print str(a)
- print str(a)
- print str(a)
- print str(a)
|
Code :
- (objet C)0
- (objet C)0
- (objet C)0
- (objet C)0
- (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 :
- class C(object):
- n = -1 # numéro de création de la précédente instance
- inst = set([]) # ensemble cumulatif des instances créées
-
- def __init__(cap):
- # Fixation du numéro d'ordre d’une instance à sa création:
- C.n += 1
- cap.numero = C.n
- # Création du compteur de noms de l'instance:
- cap.cnt_noms = 1
- # Enregistrement de l'instance créée et affichage du suivi du déroulement:
- C.inst.add(cap)
- print 'Ensemble C.inst apres initialisation :\n '+\
- ' , '.join(repr(y)[-11:-5]+'~'+repr(y)[-5:-1] for y in C.inst)
-
- def __str__(self):
- return "(objet C)%i repéré par %i nom%s"\
- % (self.numero, self.cnt_noms, (self.cnt_noms>1)*'s')
-
- def aliasing(self,ch):
- globals()[ch] = self
- self.cnt_noms += 1
- def delete(self,ci):
- if self.cnt_noms==1: # il ne reste plus qu'une référence sur self, donc:
- # - on élimine tout ce qui concerne l'instance concernée self
- self.__class__.n -= 1
- self.__class__.inst.remove(self)
- # - on décrémente les numéros d'ordre des instances créées après self
- for instance in self.__class__.inst:
- instance.numero -= instance.numero>self.numero
- del globals()[ci]
- self.cnt_noms -= 1
- print 'Ensemble C.inst après DEL :\n '+\
- ' , '.join(repr(y)[-11:-5]+'~'+repr(y)[-5:-1] for y in C.inst)
-
- class D:
- pass
- classes_utilisateur =(C,D)
- print 'a = C()'
- a = C()
- print 'str(a) : '+str(a)
- print 'a : ',a
- print '\nb = C()'
- b = C()
- print 'str(a) : '+str(a)
- print 'a : ',a
- print 'str(b) : '+str(b)
- print 'b : ',b
- print '\nc = C()'
- c = C()
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print '\nd = C()'
- d = C()
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print '\ne = C()'
- e = C()
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print 'e : '+str(e)
- print "\nc.aliasing('f')"
- c.aliasing('f')
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print 'e : '+str(e)
- print 'f : '+str(f)
- print "\ng = C()"
- g = C()
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print 'e : '+str(e)
- print 'f : '+str(f)
- print 'g : '+str(g)
- print "\nf.aliasing('h')"
- f.aliasing('h')
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print 'e : '+str(e)
- print 'f : '+str(f)
- print 'g : '+str(g)
- print 'h : '+str(h)
- print "\nf.delete('f')"
- f.delete('f')
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print 'e : '+str(e)
- try: print 'f : '+str(f)
- except: print 'f : identifiant detruit'
- print 'g : '+str(g)
- print 'h : '+str(h)
- print "\nb.aliasing('i')"
- b.aliasing('i')
- print 'a : '+str(a)
- print 'b : '+str(b)
- print 'c : '+str(c)
- print 'd : '+str(d)
- print 'e : '+str(e)
- try: print 'f : '+str(f)
- except: print 'f : identifiant detruit'
- print 'g : '+str(g)
- print 'h : '+str(h)
- print 'i : '+str(i)
- print "\nc.delete('c')"
- c.delete('c')
- print 'a : '+str(a)
- print 'b : '+str(b)
- try: print 'c : '+str(c)
- except: print 'c : identifiant detruit'
- print 'd : '+str(d)
- print 'e : '+str(e)
- try: print 'f : '+str(f)
- except: print 'f : identifiant detruit'
- print 'g : '+str(g)
- print 'h : '+str(h)
- print 'i : '+str(i)
- print '\nj = C()'
- j = C()
- print 'a : '+str(a)
- print 'b : '+str(b)
- try: print 'c : '+str(c)
- except: print 'c : identifiant detruit'
- print 'd : '+str(d)
- print 'e : '+str(e)
- try: print 'f : '+str(f)
- except: print 'f : identifiant detruit'
- print 'g : '+str(g)
- print 'h : '+str(h)
- print 'i : '+str(i)
- print 'j : '+str(j)
- print "\nh.delete('h')"
- h.delete('h')
- print 'a : '+str(a)
- print 'b : '+str(b)
- try: print 'c : '+str(c)
- except: print 'c : identifiant detruit'
- print 'd : '+str(d)
- print 'e : '+str(e)
- try: print 'f : '+str(f)
- except: print 'f : identifiant detruit'
- print 'g : '+str(g)
- try: print 'h : '+str(h)
- except: print 'h : identifiant detruit'
- print 'i : '+str(i)
- print 'j : '+str(j)
- print "\na.delete('a')"
- a.delete('a')
- try: print 'a : '+str(a)
- except: print 'a : identifiant detruit'
- print 'b : '+str(b)
- try: print 'c : '+str(c)
- except: print 'c : identifiant detruit'
- print 'd : '+str(d)
- print 'e : '+str(e)
- try: print 'f : '+str(f)
- except: print 'f : identifiant detruit'
- print 'g : '+str(g)
- try: print 'h : '+str(h)
- except: print 'h : identifiant detruit'
- print 'i : '+str(i)
- print 'j : '+str(j)
|
Code :
- a = C()
- Ensemble C.inst apres initialisation :
- 0x0109~EDB0
- str(a) : (objet C)0 repéré par 1 nom
- a : (objet C)0 repéré par 1 nom
- b = C()
- Ensemble C.inst apres initialisation :
- 0x0109~ED90 , 0x0109~EDB0
- str(a) : (objet C)0 repéré par 1 nom
- a : (objet C)0 repéré par 1 nom
- str(b) : (objet C)1 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c = C()
- Ensemble C.inst apres initialisation :
- 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 1 nom
- d = C()
- Ensemble C.inst apres initialisation :
- 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0 , 0x010B~7AB0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 1 nom
- d : (objet C)3 repéré par 1 nom
- e = C()
- Ensemble C.inst apres initialisation :
- 0x0109~ED90 , 0x0109~EDB0 , 0x010B~7B10 , 0x00AD~05D0 , 0x010B~7AB0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 1 nom
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- c.aliasing('f')
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 2 noms
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : (objet C)2 repéré par 2 noms
- g = C()
- Ensemble C.inst apres initialisation :
- 0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 2 noms
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : (objet C)2 repéré par 2 noms
- g : (objet C)5 repéré par 1 nom
- f.aliasing('h')
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 3 noms
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : (objet C)2 repéré par 3 noms
- g : (objet C)5 repéré par 1 nom
- h : (objet C)2 repéré par 3 noms
- f.delete('f')
- Ensemble C.inst après DEL :
- 0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 1 nom
- c : (objet C)2 repéré par 2 noms
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : identifiant detruit
- g : (objet C)5 repéré par 1 nom
- h: (objet C)2 repéré par 2 noms
- b.aliasing('i')
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 2 noms
- c : (objet C)2 repéré par 2 noms
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : identifiant detruit
- g : (objet C)5 repéré par 1 nom
- h : (objet C)2 repéré par 2 noms
- i : (objet C)1 repéré par 2 noms
- c.delete('c')
- Ensemble C.inst après DEL :
- 0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 2 noms
- c : identifiant detruit
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : identifiant detruit
- g : (objet C)5 repéré par 1 nom
- h : (objet C)2 repéré par 1 nom
- i : (objet C)1 repéré par 2 noms
- j = C()
- Ensemble C.inst apres initialisation :
- 0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x010B~7B30 , 0x0109~ED90 , 0x0109~EDB0 , 0x00AD~05D0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 2 noms
- c : identifiant detruit
- d : (objet C)3 repéré par 1 nom
- e : (objet C)4 repéré par 1 nom
- f : identifiant detruit
- g : (objet C)5 repéré par 1 nom
- h : (objet C)2 repéré par 1 nom
- i : (objet C)1 repéré par 2 noms
- j : (objet C)6 repéré par 1 nom
- h.delete('h')
- Ensemble C.inst après DEL :
- 0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x010B~7B30 , 0x0109~ED90 , 0x0109~EDB0
- a : (objet C)0 repéré par 1 nom
- b : (objet C)1 repéré par 2 noms
- c : identifiant detruit
- d : (objet C)2 repéré par 1 nom
- e : (objet C)3 repéré par 1 nom
- f : identifiant detruit
- g : (objet C)4 repéré par 1 nom
- h : identifiant detruit
- i : (objet C)1 repéré par 2 noms
- j : (objet C)5 repéré par 1 nom
- a.delete('a')
- Ensemble C.inst après DEL :
- 0x010B~7A90 , 0x010B~7AB0 , 0x010B~7B10 , 0x010B~7B30 , 0x0109~ED90
- a : identifiant detruit
- b : (objet C)0 repéré par 2 noms
- c : identifiant detruit
- d : (objet C)1 repéré par 1 nom
- e : (objet C)2 repéré par 1 nom
- f : identifiant detruit
- g : (objet C)3 repéré par 1 nom
- h : identifiant detruit
- i : (objet C)0 repéré par 2 noms
- j : (objet C)4 repéré par 1 nom
|
Message édité par eyquem le 15-09-2010 à 11:15:43
|