Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class constructor with default arguments [duplicate]

Tags:

python

oop

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

Can anyone explain the following strange behaviour?

I have the following class:

class Zoo:
    def __init__(self,alist=[]):
        self.animals = alist

    def __len__(self):
        return len(self.animals)

    def add(self,a):
        self.animals.append(a)

and when I do the following,

In [38]: z=Zoo()
In [39]: z.add(2)
In [40]: z.add(23)
In [41]: len(z)
Out[41]: 2

In [42]: z2=Zoo()

In [43]: len(z2)
Out[43]: 2

Why is z2.animals not an empty list?

Thanks, Matthias

like image 290
thias Avatar asked Apr 12 '12 12:04

thias


People also ask

Can Python constructors have default arguments?

6.7 CONSTRUCTORS WITH DEFAULT ARGUMENTSIt is possible to have a constructor with default arguments.. It means that if the constructor is defined with n parameters, we can invoke it with less than n arguments specified in the call. Anyname ( para1,para2,para3,para4 =val4, … paran = valn);

Can we overload default constructor in Python?

In the python method and constructor, overloading is not possible.

How do you initialize a default constructor in Python?

In short, Python's instantiation process starts with a call to the class constructor, which triggers the instance creator, . __new__() , to create a new empty object. The process continues with the instance initializer, . __init__() , which takes the constructor's arguments to initialize the newly created object.

What is __ init __ in Python?

The __init__ method is the Python equivalent of the C++ constructor in an object-oriented approach. The __init__ function is called every time an object is created from a class. The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.


1 Answers

You are mutating the default argument in your constructor (you are just copying a reference to the same list into each of your instances). You can fix this as follows:

class Zoo:
    def __init__(self,alist=None):
        self.animals = alist or []

    def __len__(self):
        return len(self.animals)

    def add(self,a):
        self.animals.append(a)
like image 198
Steve Mayne Avatar answered Sep 23 '22 06:09

Steve Mayne