Newbiefrage zu Klassen mit Attributen

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
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Hallo,

habe gerade ein Python-Tutorial durchgearbeitet und jeweils auch die Beispiele durchexerziert. Da ich schon des Pascal, des C, des Java und des C# halbwegs mächtig bin und damit auch schon gössere Anwendungen (auch Android-Apps) geschrieben habe, bin ich kein absoluter Anfänger. Jetzt habe ich damit angefangen, ein Projekt umzusetzen, was ich vorher schon mit C++ umsetzen wollte. C++ hätte ich jetzt auch neu erlernen müssen, es hat mir aber überhaupt nicht gefallen und jetzt habe ich mich für Python entschieden. Wegen der komplett anderen "Denke" von Python (was mir auch wahnsinnig gut gefällt) habe ich direkt aber auch schon wieder Verständnisprobleme, was die Klassen angeht (war für mich als damaliger C-Programmierer in Java schon echt irgendwie schwierig für mich... :oops: ):

Ich brauche für mein Programm zentrale Datenstrukturen, die ich vorher in C mal mit structs und in Java und C# mit Klassen realisiert hatte.

Die Klassen soll Strings, Integers, doubles und Arrays als Member-Attribute enthalten.

Beim Instanzieren dieser Klassen (sagen wir mal eine namens AKlasse) sollen diese initialisiert werden:
- entweder mit defaults (in __init__(self,name="nix",monat=1,...):) mit ak=AKlasse()
- oder mit Parametern mit ak=AKlasse("Jupp", 5, ...)

Jetzt möchte ich die Daten/Attribute komplett ändern. Das würde ich jetzt so machen, indem ich die Klasse wieder einfach neu auf das gleiche Objekt instanziere (wieder mit ak=AKlasse("Jupp", 5, ...)), also __init__(...) benutzen.

Ist das richtig so ? :?:
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

mephisto-online hat geschrieben:Jetzt möchte ich die Daten/Attribute komplett ändern [...] indem ich die Klasse wieder einfach neu auf das gleiche Objekt instanziere (wieder mit ak=AKlasse("Jupp", 5, ...)), also __init__(...) benutzen.

Ist das richtig so ? :?:
Jein. Was du dadurch bekommst, ist ein neues Exemplar der AKlasse (im folgenden kurz A):

Code: Alles auswählen

class A:
    def __init__(self, name, age):
        self.name = name
        self.age = age

a = A('joe', 35)
b = a
a = A('jim', 23)

print(a.name, a.age)
print(b.name, b.age)
Ergebnis:

Code: Alles auswählen

jim 23
joe 35
Bei der Zuweisung an eine Variable wird nur eine Referenz auf ein Objekt überschrieben, nicht das referenzierte Objekt. Es ist ähnlich wie eine Pointer-Zuweisung in C, nur dass die Referenz kein Pointer ist, sondern die Assoziation eines Strings (dem Namen der Variablen) mit einem Objekt in einem Namespace. Namespaces werden in Python hinter den Kulissen mittels Dictionaries implementiert. Gewissermaßen besteht das Objektmodell von Python in einer dünnen Schicht aus Syntax über einer Menge von Dictionaries.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Noch eine Anmerkung:

Code: Alles auswählen

class A:
    def __init__(self, name, age):
        self.name = name
        self.age = age

a = A('joe', 35)
b = a
print(id(a))
print(id(b))
Ergebnis:

Code: Alles auswählen

2145203020
2145203020
Die id()-Funktion liefert für jedes Objekt einen eindeutigen, und für jedes Objekt identischen, Wert. In CPython (die in C geschriebene Standard-Implementierung von python.org) ist das die Adresse des Objekts im Speicher. Das ist aber ein Implementierungsdetail und andere Implementationen sind frei, das anders zu handhaben.

Das Gesetz zu id() ist:

Code: Alles auswählen

(a is b) == (id(a) == id(b)
Wie man an dem Beispiel oben sehen kann, verweisen dort a und b auf dasselbe Objekt. Bei der Zuweisung wurde also nicht das Objekt kopiert, sondern nur eine Referenz auf das Objekt. In C dagegen würde man bei einer Zuweisung erwarten, dass der Wert rechts von Zuweisungsoperator nach links kopiert wird und dieser Wert wäre letztlich die Folge von Bytes im Speicher, in denen das Objekt "liegt". Ebenso wäre die Variable, der etwas zugewiesen wird, nur der Name einer - hoffentlich gleich langen - Folge von Bytes im Speicher.
In specifications, Murphy's Law supersedes Ohm's.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

Hallo,

@pillmuncher
so ein Tutorial, was ich durchgearbeitet habe (http://de.wikibooks.org/wiki/Python_unt ... cite_ref-6), kratzt natürlich nur an der Oberfläche. Weil ich aber "Learning by doing" brauche, war es erst mal nicht schlecht ! Auf der anderen Seite muss ich aber auch erst alles ganz genau wissen, bevor ich etwas wirklich damit anfangen kann.
pillmuncher hat geschrieben:Bei der Zuweisung an eine Variable wird nur eine Referenz auf ein Objekt überschrieben, nicht das referenzierte Objekt. Es ist ähnlich wie eine Pointer-Zuweisung in C, nur dass die Referenz kein Pointer ist, sondern die Assoziation eines Strings (dem Namen der Variablen) mit einem Objekt in einem Namespace. Namespaces werden in Python hinter den Kulissen mittels Dictionaries implementiert. Gewissermaßen besteht das Objektmodell von Python in einer dünnen Schicht aus Syntax über einer Menge von Dictionaries.
Gegen diese Erklärung ist alles, was ich bisher über Python als Beschreibung gelesen habe, kalter Kaffee ! Als alter C-Programmierer, der schon mal "an der Basis" gearbeitet hat, ist es genau das, was die Sache mit Python hinlänglich beschreibt und mir noch einmal bestätigt, dass es genau das ist, wonach ich immer gesucht habe ! Bei Java z.B. habe ich immer nicht genau gewusst, was ich da jetzt gerade genau gemacht habe und mich damit zufrieden gegeben, dass es funktioniert.

Das bestätigt mir aber auch, was ich vermutet habe, dass ich bei gleich bleibendem Namen mit einer "neuen" Variablen den Inhalt der "alten" verliere.

Ich hoffe, dass ich das jetzt richtig geschnackelt habe ... :roll:
BlackJack

@mephisto-online: Bei Java funktioniert das nahezu genau so mit den Objekten und Zuweisungen. Nur das den Namen eine statische Typinformation zugeordnet ist die verhindert das man beliebige Objekte zuweisen kann.

Und das man nach einer Zuweisung von einem neuen Wert an einen Namen über den Namen nicht mehr an den alten Wert kommt, ist auch in den meisten Programmiersprachen so, inklusive in C und in Java.
mephisto-online
User
Beiträge: 167
Registriert: Sonntag 29. September 2013, 17:05

BlackJack hat geschrieben:@mephisto-online: Bei Java funktioniert das nahezu genau so mit den Objekten und Zuweisungen. Nur das den Namen eine statische Typinformation zugeordnet ist die verhindert das man beliebige Objekte zuweisen kann.
Genau das verwirrt mich ja jetzt bei Python ein wenig, weil ich es anders gewohnt bin.
Und das man nach einer Zuweisung von einem neuen Wert an einen Namen über den Namen nicht mehr an den alten Wert kommt, ist auch in den meisten Programmiersprachen so, inklusive in C und in Java.
Genau deswegen hatte ich es ja sicherheitshalber noch mal nachgefragt, eben, ob das denn jetzt in Python genau so ist. Entschuldigung, das war dumm von mir.
Antworten