Optional parameter object re-used when instantiating multiple objects

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Nov 15 21:37:57 EST 2008


On Sat, 15 Nov 2008 01:40:04 -0800, Rick Giuly wrote:

> Hello All,
> 
> Why is python designed so that b and c (according to code below)
> actually share the same list object? It seems more natural to me that
> each object would be created with a new list object in the points
> variable.

That's not natural *at all*. You're initialising the argument "points" 
with the same list every time. If you wanted it to have a different list 
each time, you should have said so. Don't blame the language for doing 
exactly what you told it to do.


> class Blob:
>     def __init__(self, points=[]):
>         self._points = points

Let's analyze this. You create a method __init__. That function is 
created *once*. As part of the process of creating the function, the 
argument "points" is given the default value of an empty list. The 
creation of that empty list happens *once*, when the method is created. 
In the body of the function, you set the _points attribute to points. 
Naturally it is the same list object.

Since the method is only created once, it is only natural that the 
default value is also only created once. If you want something to be 
created each time the function is called, you have to put it inside the 
body of the function:

class Blob:
    def __init__(self, points=None):
        if points is None: 
            points = []
        self._points = points

Now you will have _points set to a unique empty list each time.



This is no different from doing this:

alist = []
b1 = Blob(alist)
b2 = Blob(alist)

Would you be surprised that b1 and b2 share the same list? If yes, then 
you need to think about how Python really works, rather than how you 
imagine it works.



-- 
Steven



More information about the Python-list mailing list