0

I have a Node class, which has a name and an array in it, and a Graph class which should have an array of Node objects:

class Node:
    name = ""
    next = []

class Graph:
    nodes = [] # nodes is an array consisting of Node objects 

I've made a function which appends a Node object into the Graph when passed a string.


def add_new(self, new_name):
        new_node = Node
        new_node.name = new_name
        self.nodes.append(new_node)
        print("New node given name: ", new_name)
        print("New length of nodes: ", len(self.nodes))

graph2 = Graph

add_new(graph2, "Jim")
add_new(graph2, "Dwight")
add_new(graph2, "Andy")

print("Node names: ")
for i in range(0,3):
    print(graph2.nodes[i].name)

Instead of actually appending the new_node, the function seems to replace all the previous elements of the node array with the latest new_node object.

python -u "c:\Users\Vishnu\CS-Project\why.py"
New node given name:  Jim
New length of nodes:  1
New node given name:  Dwight
New length of nodes:  2
New node given name:  Andy
New length of nodes:  3
Node names:
Andy
Andy
Andy

How does this happen? Isn't new_node a local variable and shouldn't it be fresh every iteration of the function?

DireVish
  • 1
  • 1

2 Answers2

1

Attributes set at class level are static - that is, shared by all instances of the class. You probably want:

class Node:
    def __init__(self):
        self.name = ""
        self.next = []

class Graph:
    def __init__(self):
        self.nodes = []

Also, you need to call the class to instantiate - so you want new_node = Node() and graph2 = Graph().

brunns
  • 2,689
  • 1
  • 13
  • 24
  • 1
    Thanks! [Here's some reference](https://stackoverflow.com/questions/9056957/correct-way-to-define-class-variables-in-python#9056994) if someone ever stumbles across this. – DireVish Apr 17 '19 at 18:52
0

You need to actually instantiate the Node and Graph classes.

class Node:
    def __init__(self, name):
        self.name = name

class Graph:

    def __init__(self):
        self.nodes = list()

    def add_new(self, new_name):
        new_node = Node(new_name)
        self.nodes.append(new_node)
        print("New node given name: ", new_name)
        print("New length of nodes: ", len(self.nodes))

graph2 = Graph()

graph2.add_new("Jim")
graph2.add_new("Dwight")
graph2.add_new("Andy")

print("Node names: ")
for i in range(0,3):
    print(graph2.nodes[i].name)

Remember that self is a reference to the object instantiation of your class. It is part of the class definition, and a python specifica syntax.

Creating a python object from a class, is done by simply adding () to the end of the class. In Java you have to say new as well.

You define a class like this:

class Person():
    def __init__(self, some_var):
        self.some_var = some_var
    def some_method(self, msg):
        print("He said:", msg)

Then you create an object from it like this:

my_person = Person('my_var')

Then you can use a method in it like this:

my_person.some_method('FooBar')
André C. Andersen
  • 8,955
  • 3
  • 53
  • 79