Cong Hui
Cong Hui

Reputation: 633

Append to the same list

I am from a solid C/C++ background, so please bear with me if my question is silly.

Here I have two classes that declared to encapsulate data,

class Node:
    Term = ""
    TermInfo = []
    def __init__(self,S,Info):
        self.Term = S
        self.TermInfo.append(Info)

class TermInfo:
    DocID = 0
    Freq = 0
    def __init__(self,ID,F):
        self.DocID = ID
        self.Freq = F

and I was trying to manipulate them this way

 Info = TermInfo(ID,0)
 node = Node(j,Info)
 Dict[j] = node

Basically I was trying to construct a dictionary that contains nodes that are made of a string "Term" and a list of "Terminfo", I was expecting that each node has its own copy. However, after I called the three lines twice in a row

Info = TermInfo(ID,0)
node = Node(j,Info)
Dict[j] = node

Info = TermInfo(ID,0)
node = Node(j,Info)
Dict[j] = node

I was surprised to see that the two lists of "TermInfo" were pointing to the same memory address and the second append() also changed the first list,So how do I make sure each node has its own copy instead of pointing to the same address? Thanks

Upvotes: 2

Views: 95

Answers (2)

wRAR
wRAR

Reputation: 25569

Only attributes assigned in __init__ and after object construction are instance attributes. Attributes assigned in the class definition are class attributes, similar to static class members in other languages. So if you want to have a per-instance attribute, assign its initial value in __init__.

Upvotes: 0

mgilson
mgilson

Reputation: 310257

Short answer:

create a new list in __init__.

def __init__(self,S,Info):
    self.Term = S
    self.TermInfo = [Info]

Long answer:

This has to do with how python looks up attributes. When you do: instance.attribute, python first looks for the attribute on the instance. If it's not found there, it looks for the attribute on the class. Here you have a list attribute on the class and you keep on appending to that attribute via the instance. So when you have the line:

self.TermInfo.append(whatever)

Python first looks at self. however, self doesn't have a TermInfo attribute, so then python looks at self.__class__ (Node in this case) for the TermInfo attribute -- and it finds it so it appends to the Node.TermInfo list.

Upvotes: 4

Related Questions