Seite 1 von 1

Klassen-Constructor

Verfasst: Donnerstag 2. September 2010, 16:43
von matthias11
Ich verstehe nicht warum bei folgendem code list[1].vari eine Kopie von list[0].vari zu sein scheint?! IMO sollte list[1].vari als [] initialisiert sein.

Bitte um Hilfe/Erklärung

Code: Alles auswählen

>>> class Klasse:
...      def __init__(self, vari = []):
...             self.vari = vari
...
>>> list = []
>>> list.append(Klasse())
>>> list[0].vari
[]
>>> list[0].vari.append("eins")
>>> list[0].vari.append("zwei")
>>> list.append(Klasse())
>>> list[0]
<__main__.Klasse instance at 0xb778fe4c>
>>> list[1]
<__main__.Klasse instance at 0xb778feac>
>>> list[0].vari
['eins', 'zwei']
>>> list[1].vari
['eins', 'zwei']

Re: Klassen-Constructor

Verfasst: Donnerstag 2. September 2010, 16:48
von jbs
Das hat damit zu tun, dass die defaultwerte von Funktionen (und daher auch der Methoden) nur einmal ausgewertet werden und man immer dasselbe Objekt übergeben bekommt. Listen sind mutable und daher arbeitest du immer auf der gleichen Liste.

Besser:

Code: Alles auswählen

def foo(default=None):
    default = default or [] #oder was ähnliches

Re: Klassen-Constructor

Verfasst: Donnerstag 2. September 2010, 16:51
von BlackJack
@matthias11: Das hat nichts mit Klassen zu tun, sondern wann Defaultargumente von Funktionen ausgewertet. Das passiert *einmal* wenn die ``def``-Anweisung ausgeführt wird. Das Ergebnis davon merkt sich das Funktionsobjekt und bei jedem Aufruf wird das gemerkte Objekt an den Namen gebunden (wenn kein Argument dafür übergeben wurde). Darum hast Du da nur eine Liste die bei jedem Exemplar der Klasse und bei jedem Aufruf der Funktion das selbe Objekt ist.

Darum sind veränderbare Objekte als Defaultargumente keine gute Idee. Es sei denn man will das Verhalten ausnutzen.

Üblicherweise belegt man solche Defaultargumente mit `None` und testet das in der Funktion.