0

Here is a code I'm working on:

class Node:
    count = 0

    def __init__(self):
        Node.id = Node.count
        Node.count += 1

    @classmethod
    def get_count(cls):
        return Node.count


class Element:

    count = 0

    def __init__(self, type = "MTH20", group = 0):
        self.type = type
        self.group = group
        Element.count += 1

    def define_element(self):
        self.nodes = [-1]*3

        for l in range(len(self.nodes)):
            if self.nodes[l] == -1:
                self.nodes[l] = Node()
                print(self.nodes[l].id)

        for l in range(len(self.nodes)):

            print(self.nodes[l].id)  

ga = Element()

ga.define_element()

I would expect the output of this code to be:

0
1
2
0
1
2

However I get this:

0
1
2
2
2
2

My conclusion is that somehow the id attribute of a node object is overwritten when constructing a new node. However, I don't understand why it would do so, or how to avoid that.

Can anyone point out what I did wrong?

Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73
gazoh
  • 237
  • 3
  • 11
  • Replace Node.id = Node.count with self.id = Node.count – Jérôme Mar 26 '18 at 13:31
  • 1
    Possible duplicate of [Python: Difference between class and instance attributes](https://stackoverflow.com/questions/207000/python-difference-between-class-and-instance-attributes) – Aran-Fey Mar 26 '18 at 13:32
  • When you set `Node.id = Node.count`, you're setting a _class attribute_. You want the id to be an _instance_ attribute, so use `self.id = Node.count`. – Aran-Fey Mar 26 '18 at 13:33

1 Answers1

2

With Node.id you are accessing a class attribute. You want to store ids as instance attributes by doing self.id.

class Node:
    count = 0

    def __init__(self):
        self.id = Node.count # We want id to be an attribute of that specific node
        Node.count += 1

About your code

I want to point out that your Element.define_element method could be written in a more concise natural way.

class Element:

...

def define_element(self):
        self.nodes = [Node() for _ in range(3))]

        for node in self.nodes:
                print(node)
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73