Python instances and attributes: is this a mistake, or did I realize this is completely wrong?

Suppose you have something like this:

class intlist:
        def __init__(self,l = []):
                self.l = l
        def add(self,a):
                self.l.append(a)

def appender(a):
        obj = intlist()
        obj.add(a)
        print obj.l

if __name__ == "__main__":
        for i in range(5):
                appender(i)

The function creates an intlist instance and calls this new instance, adding a method to the instance attribute l.

What the output of this code looks like:

[0]

[0, 1]

[0, 1, 2]

[0, 1, 2, 3]

[0, 1, 2, 3, 4]

? If i switch

obj = intlist()

from

obj = intlist(l=[])

I get the desired result

[0]

[1]

[2]

[3]

[4]

Why is this happening?

thank

+5
source share
7 answers

Ah, you hit one of the common Python errors: the default values ​​are calculated once, and then reused. Thus, every time it is called __init__, the same list is used.

, :

def __init__(self, l=None):
    self.l = [] if l is None else l

Python ( ).

: .

+14

l=[] __init__, . - :

class intlist:
    def __init__(self, l=None):
        if l is None:
            self.l = []
        else:
            self.l = l
+4

,

def __init__(self,l = []):

Python , [], . , obj = intlist() , .

l None, ( , ). , l - None, []. - l.

+3

- , __init__ .

Try:

class intlist:
        def __init__(self, l):
                self.l = l if (l is not None) else []
        def add(self,a):
                self.l.append(a)

EDIT: is not, SilentGhost

+1

obj = intlist() __init__(), .

obj = intlist(l=[]) .

+1

For more information, I suggest reading this: http://effbot.org/zone/default-values.htm

+1
source

Be careful with the default options for types such as lists and dicts. Each intlist instance gets the same list object from the default parameter.

0
source

All Articles