2017-10-16 1 views
0

Je vais avoir un problème à l'aide des listes d'objets en python:Dans la liste des objets en python, en utilisant une méthode sur un élément applique la méthode à la liste entière

Je déclare une liste d'objets comme suit:

chain = [Node(1), Node(2), Node(3), 
    Node(4), Node(5), Node(6), 
    Node(7), Node(8), Node(9)] 

avec le nœud étant une classe simple:

class Node: 

def __init__(self, data, links = []): 
    self.node_links = links 
    self.node_data = data 

def add_link(self, link): 
    self.node_links.append(link) 
(...) 
def to_str(self): 
    s = "node nb " + str(self.node_data) + " linked to:" 
    for link in self.node_links: 
     s += " Node " + str(link.node_to.node_data) 
    return s 
(...) 

Tout est ok à partir d'ici, sauf quand j'utilise la méthode add_link() à un élément dans ma liste « chaîne », il exécute la méthode sur tous les e lements de ma chaîne.

Par exemple,

chain[0].add_link(Link(chain[3], 0.25)) 

for e in chain: 
    print(e.to_str()) 

Affichera

node nb 1 linked to: Node 4 
node nb 2 linked to: Node 4 
node nb 3 linked to: Node 4 
node nb 4 linked to: Node 4 
node nb 5 linked to: Node 4 
node nb 6 linked to: Node 4 
node nb 7 linked to: Node 4 
node nb 8 linked to: Node 4 
node nb 9 linked to: Node 4 

Tous les éléments de ma liste semblent avoir été touchés par ma déclaration.

Je suis assez déconcerté par cela. J'ai essayé de chercher partout (code & internet) mais je ne peux pas trouver ce que j'ai mal fait. est-ce que quelqu'un a une idée?

+0

http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments –

+0

Il peut sembler étrange que Python a ce comportement, mais il peut être utile dans certaines situations, par exemple pour agir comme cache. Cependant, si vous voulez utiliser un argument par défaut mutable, c'est une bonne idée de commenter que vous invoquez intentionnellement ce comportement. Sinon, les personnes lisant votre code peuvent supposer que c'est un bug. –

+0

Merci à vous tous. En effet, même mon IDE m'avait prévenu des arguments mutables, en tant que noob, j'ignorais l'avertissement, j'aurais dû le regarder. –

Répondre

0

Comme par le lien Michael Butscher fourni dans le commentaire, quand vous faites

def __init__(self, data, links = []): 

Le même [] est utilisé, de sorte que tous vos nœuds font référence à la même liste. Vous pouvez modifier votre constructeur à:

def __init__(self, data, links=None): 
    self.node_links = links or [] 
    self.node_data = data