0

I have a class node something like this. It's a typical node object for a graph.

class Node(object):
    def __init__(self, data, edges = []):
        super(Node, self).__init__()
        self.data = data
        self.edges = edges
        self.visited = False

    def addEdge(self, *args):
        print(self)
        self.edges.extend(args)
        print(self.edges)

I create two objects like this -

one = Node(1)
two = Node(2)

Next I add a pointer of two to one using the addEdge method defined above -

one.addEdge(two)

Now comes the surprising bit. When I check the values of one.edges and two.edges I get this -

one.edges [<main.Node object at 0x109ed3e50>]

two.edges [<main.Node object at 0x109ed3e50>].

If you see both the objects have gotten the value. I'm quite puzzled at this and have no idea why this is happening. Is this how python behaves? If so can you explain this behaviour?

2

1 Answer 1

3

You need to be careful when using an array literal as a default value because you don't get a new array with each instance — you get a reference to the same one. In your example you will see:

>> one.edges is two.edges
True

You need to do something to make sure you get a new array each time. One things you can do is:

self.edges = list(edges)

Another option is:

def __init__(self, data, edges = None):

   if edges is None:
        self.edges = []
   else:
        self.edges = edges

But edges is still mutable so it may also lead to subtle bugs if the caller is not expecting it to be changed.

Sign up to request clarification or add additional context in comments.

4 Comments

So this edges=[] in the init method is the culprit?
Yes, many will say it's a bad idea to use mutable objects as default parameters.
Ok. That was unexpected. Does the same happen when we pass {} literals as default parameters?
Yes, @RajKumar the same thing will happen.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.