Reputation: 633
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
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
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