Ashley
Ashley

Reputation: 23

Issue while appending Class Object to a list variable in another instance of the same Class Object

I am trying to write a simple code in Python. I'm still weak at the fundamentals of Python and I'm stuck on this issue. I have an inner Class Node(). It has an attribute routeNodes in it which is a list. I am using it to store other Instances of the same Class Object(Node()). So I first initialize the Class firstNode and give it some dummy values.

Then I run a for loop for 10 iterations. In each of the iterations I create another instance of the same Node() class. I then append the firstNode object (which is again an instance of Node()) to each of these secondNode classes.

It adds the firstNode to the routeNode list variable of the secondeNode.

But it also adds firstnode object to the routenode list variable of its own class object!

The same firstNode Object gets appended to both the class objects. Why does this happen? Can I not add class objects like this? and how do I stop it from happening?

Attaching my code. You can run it in a test class and debug the "secondNode.addRouteNodes(firstNode)" line and you'll understand my problem.

class Node:
    kms = 0
    cumulativeKms = 0
    routeNodes = []
    nodeName = ""

    def __init__(self, nodeName):
        self.nodeName = nodeName

    def setNodeName(self, nodeName):
        self.nodeName = nodeName

    def getNodeName(self):
        return self.nodeName

    def setKms(self, kms):
        self.kms = kms

    def getKms(self):
        return self.kms

    def setCumulativeKms(self, kms):
        self.cumulativeKms = self.cumulativeKms + kms

    def getCumulativeKms(self):
        return self.cumulativeKms

    def addRouteNodes(self, nodes):
        self.routeNodes.append(nodes)

    def getRouteNodes(self):
        return self.routeNodes


firstNode = Node("first")

firstNode.setKms(0)

firstNode.setCumulativeKms(0)

for i in range(10):

    secondNode = Node('new'+str(i))

    secondNode.setKms(10)

    secondNode.setCumulativeKms(10)

    routes = firstNode.getRouteNodes()

    for route in routes:
        secondNode.addRouteNodes(route)

    secondNode.addRouteNodes(firstNode)

print("Done")

Upvotes: 1

Views: 906

Answers (1)

Rolf Lobo
Rolf Lobo

Reputation: 112

class Node:
    kms = 0
    cumulativeKms = 0
    routeNodes = []
    nodeName = ""

These variables don't belong to each new class object created but rather are shared between the objects and hence the first class gets appended to its own routeNodes variable over here : secondNode.addRouteNodes(route).They are called class variables.

A solution would be to initialize the variables inside the constructor like below :

self.kms = 0
self.cumulativeKms = 0
self.routeNodes = []
self.nodeName = ""

These are called instance variables.You need this.

So the updated code would be :

class Node:

    def __init__(self):
        self.kms = 0
        self.cumulativeKms = 0
        self.routeNodes = []
        self.nodeName = ""

    def setNodeName(self, nodeName):
        self.nodeName = nodeName

    def getNodeName(self):
        return self.nodeName

    def setKms(self, kms):
        self.kms = kms

    def getKms(self):
        return self.kms

    def setCumulativeKms(self, kms):
        self.cumulativeKms = self.cumulativeKms + kms

    def getCumulativeKms(self):
        return self.cumulativeKms

    def addRouteNodes(self, nodes):
        self.routeNodes.append(nodes)

    def getRouteNodes(self):
        return self.routeNodes


firstNode = Node()

firstNode.setNodeName("first")

firstNode.setKms(0)

firstNode.setCumulativeKms(0)

for i in range(10):

    secondNode = Node()

    secondNode.setNodeName('new'+str(i))

    secondNode.setKms(10)

    secondNode.setCumulativeKms(10)

    routes = firstNode.getRouteNodes()

    for route in routes:
        secondNode.addRouteNodes(route)

    secondNode.addRouteNodes(firstNode)

print("Done")

Upvotes: 1

Related Questions