Home > Mobile >  How to access object atribute inside a list of objects that is an atribute of a class in python?
How to access object atribute inside a list of objects that is an atribute of a class in python?

Time:03-16

I am trying to build a "node" class, that has 2 valued attributes and a list of children "nodes". When I try to access one of the child's children, I only get the current child list.

Here's what I am doing:

class node:

    def __init__(self, value = 0, depth = 0, child = []):
        self.value = value
        self.depth = depth
        self.child = child

a = node(1,0)
b = node(2,1)
c = node(3,1)

print("object A:",a)
print("object B:",b)
print("object C:",c)

# b and c have no children
print("Children of B:",b.child)
print("Children of C:",c.child)

a.child.append(b)
a.child.append(c)

# a now has 2 children, b and c
print("Children of A:",a.child)

# If I check "B" and "C" values it works ok
print("Value of B:",a.child[0].value)
print("Value of C:",a.child[1].value)

# but if I try to check b or c child list, I get A's children
print("Children of B:",a.child[0].child)
print("Children of C:",a.child[1].child)

What am I doing wrong?

The code can be tried here

CodePudding user response:

this is a common gotcha related to using mutable default arguments. Python initializes that list during the function definition, so all the subsequent node instances are accessing (and re-assigning) the very same list reference.

The way to fix this is to define the default to be None, and initialize the list inside the __init__ method body:

def __init__(self, value=0, depth=0, children=None):
    self.children = children or list()
    ...

CodePudding user response:

To fix this use copy() method of the list in constructor, to assign just values instead of list reference.

def __init__(self, value = 0, depth = 0, child = []):
        self.value = value
        self.depth = depth
        self.child = child.copy()
  • Related