Initialisierung von Klassen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Krie9er
User
Beiträge: 22
Registriert: Montag 30. März 2020, 20:06

Hallo Liebes Forum, ich zerbrech mir gerade schon die ganze Zeit den Kopf und habe jetzt zumindest die Ursache gefunden.
Allerdings verstehe ich noch nicht so ganz wieso Python 3.7 so agiert.

Folgende Situation/Code:

Code: Alles auswählen

class a():
    arr = []
    def __init__(self,ele):
        self.arr.append(ele)

    def add(self,ele):
        self.arr.append(ele)

cl1 = a(1)
cl1.add(2)

cl2 = a(1)
print("Array der CL1: ",len(cl1.arr))
print("Array der CL2: ",len(cl2.arr))
Ich möchte gerne 2 unterschiedliche Instanzen der Klasse a erzeugen.

Ich verstehe nicht wieso ich bei diesem Code folgenden output bekomme
Array der CL1: 3
Array der CL2: 3
Meines Verständnisses nach erzeuge ich doch aus der klasse A, 2 Instanzen (cl1 und cl2)

Somit erwarte ich eigentlich
Array der CL1: 2
Array der CL2: 1
als Ergebnis.

Wieso bekomme ich nicht das erwartete Ergebnis?

Mir ist bewusst, dass das wahrscheinlich ein totaler Anfängerfehler ist. Allerdings komme ich einfach nicht weiter.

Ich danke euch für eure Hilfe

Freundliche Grüße!
tom.somebody
User
Beiträge: 12
Registriert: Montag 15. Juli 2019, 20:39

Deine Variable: arr ist eine Klassenvariable und keine Instanzvariable. Versuch mal das:

Code: Alles auswählen

class a():
    def __init__(self,ele):
        self.arr = []
        self.arr.append(ele)

    def add(self,ele):
        self.arr.append(ele)

cl1 = a(1)
cl1.add(2)

cl2 = a(1)
print("Array der CL1: ",len(cl1.arr))
print("Array der CL2: ",len(cl2.arr))
Ich weiß, dass ich nichts weiß und jetzt wisst ihr es auch. Also Vorsicht bei meinen Beiträgen.
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Klassenattribute existieren nur einmal pro Klasse und werden auch schon bei der Definition der Klasse angelegt. Das sind globale Objekte im Namensraum der Klasse und sollen daher auch nie verändert werden, also Konstanten sein. Konstanten schreibt man komplett groß, damit man das auch sofort erkennt: ARR.
Zur Namensgebung: Klassen schreibt man mit großen Anfangsbuchstaben, damit man auch gleich erkennt, was eine Klasse ist, und die Instanz einer Klasse auch so benennen kann, nur eben klein geschrieben. Benutze keiner Abkürzungen, ele -> element, arr -> array. Wobei wir hier schon das Problem haben, dass array gar kein Array ist, sondern eine Liste, es also verwirrend ist, das array zu nennen. Nach Typen sollte man Variablen auch nicht nennen, sondern nach dem, was sie enthalten.
Wenn jetzt cl1 noch für class1 steht, haben wir das nächste Verständnisproblem: die Exemplare einer Klasse heißen Instanz.
Alle Attribute, die eine Instanz einer Klasse besitzen soll, werden in __init__ initialisiert:

Code: Alles auswählen

class Whatever():
    def __init__(self, element):
        self.elements = [element]

    def add(self, element):
        self.elements.append(element)

def main():
    instance1 = Whatever(1)
    instance1.add(2)

    instance2 = Whatever(1)

    print("Anzahl der Elemente in instance1: ", len(instance1.elements))
    print("Anzahl der Elemente in instance2: ", len(instance2.elements))
    
if __name__ == "__main__":
    main()
Krie9er
User
Beiträge: 22
Registriert: Montag 30. März 2020, 20:06

Vielen Dank für die Anmerkung, mir war nicht bewusst, dass es möglich ist in python static Variablen zu erzeugen (hier Klassenattribute).

Ich werde meinen Code verändern. Vielen vielen Dank!
Antworten