2012-04-12 16 views
7

Powiel możliwe:
“Least Astonishment” in Python: The Mutable Default ArgumentPython klasy konstruktor z domyślnych argumentów

Może ktoś wyjaśnić następujące dziwne zachowanie?

Mam następujące klasy:

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

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

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

i kiedy należy wykonać następujące czynności,

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 

Dlaczego z2.animals nie pustą listą?

Dzięki Matthias

+2

Może nie wiedział, czego szukać? Czasami trudno jest znaleźć właściwe terminy wyszukiwania, jeśli nie znasz warunków. – hopla

Odpowiedz

11

Jesteś mutacji domyślny argument konstruktora (dopiero kopiowania odniesienie do tej samej listy do każdego z przypadków). Można rozwiązać ten problem w następujący sposób:

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) 
4

Domyślna lista argumentów jest taka sama dla wszystkich instancji obiektu, stąd przypisywanie go do członka właśnie przypisuje odniesienie do tego samego obiektu.

oto przykład:

>>> class foo(): 
... def __init__(self, x = []): 
...  print id(x) 
... 
>>> x = foo() 
140284337344168 
>>> y = foo() 
140284337344168 
>>> z = foo() 
140284337344168 

widać, że x jest ten sam obiekt we wszystkich przypadkach.

+0

Świetna ilustracja mylącego i powszechnego nieporozumienia! –

Powiązane problemy