Allocation de mémoire et référence

benc77 Messages postés 1 Date d'inscription jeudi 15 juillet 2010 Statut Membre Dernière intervention 15 juillet 2010 - 15 juil. 2010 à 15:41
cs_Chouchou182 Messages postés 252 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 25 avril 2011 - 17 juil. 2010 à 02:35
Bonjour,

je vous soumet un problème bizarre de collision de variables :
Dans le code suivant, la méthode __init__ de la classe MySemTree ne semble pas réallouer un nouvel objet à chaque appel, ce qui parait fou...

ceci est illustré par les 3 dernières lignes du code :
* on crée un arbre root
* on appelle une méthode add_branch qui prend root en parametre
* on crée un nouvel arbre dans add_branch
=> et on constate au final que c'est root qui est modifié !

J'ai pu reproduire ce bug avec python 2.7,2.6 et 2.5 compilé sous macosx.
qqun a-t-il une idée ?? pouvez-vous le reproduire ?

merci,
Be.


import sys

class MySemTree:
       
       def __init__(self,label,children=[]):
              self.label = label
              self.children=children
              
       def add_child(self,tree):
              self.children.append(tree)

       def dump(self,skip=3,indent=0):
              s =  self.label+'\n'
              for child in self.children:
                     print child.label
                     #s += child.dump(indent=indent+skip)
              return s

def add_branch(tree,lblist):    
       x = MySemTree(lblist[0])
       x.add_child(MySemTree('o'))
    
def yield_empty_tree():
       return MySemTree('-ROOT-')

root = yield_empty_tree()
add_branch(root,"XXX")
root.dump()

1 réponse

cs_Chouchou182 Messages postés 252 Date d'inscription vendredi 13 juin 2003 Statut Membre Dernière intervention 25 avril 2011 1
17 juil. 2010 à 02:35
Salut,
La valeur par défaut de la variable children de la fonction __init__ est partagée par toutes les instances de la classe. Bug ou fonctionnalité, je ne connais pas suffisamment python pour me prononcer.

Voir l'exemple ci-dessous:

class bug:
  def __init__(self, data=[]):
    self.data = data

  def push(self, d):
    self.data.append(d)

  def show(self):
    print ' '.join(self.data)

a = bug()
a.push('Hello')
b = bug()
b.push('World!')
c = bug([])
c.push('Seul')

a.show()
b.show()
c.show()


Remède? Supprimer ce '=[]' dans la définition de __init__.

Bonne prog,
0
Rejoignez-nous