Aries hat geschrieben:Ich habe auch herausgefunden, dass folgendes funktioniert:
Frage: Was bewirkt es, wenn man "object" in die Klammer schreibt?
In Python schreibt man bei der Klassendefinition die Name derjenigen Klassen, von denen man erben möchte, in runden Klammern mit Kommata getrennt zwischen den Namen der Klasse, die man definiert, und den Doppelpunkt:
Ein Paar leere Klammern bedeuten genau dasselbe, wie gar keine Klammern. Ich würde sie weglassen, da sie keinerlei Funktion haben, sondern nur für optischen Lärm sorgen. Von
object erbt man in Python 2.x, wenn man sog.
new style classes definieren möchte, im Gegensatz zu
old style classes. Letzere können bestimmte Dinge nicht, zB.
Descriptoren, was allerdings ein etwas fortgeschritteneres Thema ist, mit dem du dich vorerst nicht belasten solltest. In Python 3.x braucht man nicht mehr explizit von
object zu erben, da es da keine
old style classes mehr gibt und alle Klassen automatisch von
object erben.
Im Übrigen ist der Code der Klasse
A oben nicht äquivalent zur Definition meiner Klasse
TypeA. Der Block, der dem Klassendefinitionsheader folgt, bildet einen Namensraum, und zwar den der Klasse, nicht den Namensraum eines Objekts der Klasse. Folglich gehören die dort definierten Namen zur Klasse. In Python funktioniert die Auflösung eines qualifizierten Namens (also einem mit der Struktur <Zielobjekt>.<Name>) so, <Name> zuerst im Namensraum des Zielobjekts gesucht wird, und wenn er da nicht gefunden wurde, in der Klasse von Zielobjekt. Das Ganze wird noch komplizierter, wenn es Zuweisungen gibt, da es davon abhängt, wem was zugewiesen wird:
Code: Alles auswählen
>>> class C:
... x = 1
...
>>> a = C()
>>> print(C.x, a.x)
1 1
>>> C.x = 2
>>> print(C.x, a.x)
2 2
>>> a.x = 3
>>> print(C.x, a.x)
2 3
>>> del a.x
>>> print(C.x, a.x)
2 2
Wenn man in der Dokumentation nachliest, wie das alles funktioniert, wird einem auch klar, warum das so funktioniert und funktionieren muss. Am Anfang kann es allerdings verwirrend sein. Deswegen schlage ich vor, einfach den von mir gezeigten Weg einzuschlagen, und
__init__()-Methoden zu schreiben.
Aries hat geschrieben:Code: Alles auswählen
for Zaehler1:=1 to Staatenanzahl do
for Zaehler2:=1 to Staat[Zaehler1].Bundeslaenderanzahl do
for Zaehler3:=1 to Staat[Zaehler1].Bundesland[Zaehler2].Regierungsbezirkanzahl do
for Zaehler4:=1 to Staat[Zaehler1].Bundesland[Zaehler2].Regierungsbezirk[Zaehler3].Kreisanzahl do
Staat[Zaehler1].Bundesland[Zaehler2].Regierungsbezirk[Zaehler3].Kreis[Zaehler4].Gewinn :=
Staat[Zaehler1].Bundesland[Zaehler2].Regierungsbezirk[Zaehler3].Kreis[Zaehler4].Einnahmen -
Staat[Zaehler1].Bundesland[Zaehler2].Regierungsbezirk[Zaehler3].Kreis[Zaehler4].Ausgaben;
In Python würde man sowas eher so machen:
Code: Alles auswählen
for staat in staaten:
for bundesland in staat.bundeslaender:
for bezirk in bundesland.bezirke:
for landkreis in bezirk.landkreise:
landkreis.gewinn = landkreis.einnahmen - landkreis.ausgaben
Vorausgesetzt natürlich, dass
staat.bundeslaender,
bundesland.bezirke und
bezirk.landkreise geeignete Datenstrukturen sind, zB. Mengen oder Listen. Oder man definiert einfach, dass jeder Staat die Menge seiner Bundesländer, jedes Bundesland die seiner Bezirke und jeder Bezirk der seiner Landkreise ist, indem man die zugrunde liegenden Klassen iterierbar macht:
Code: Alles auswählen
for staat in staaten:
for bundesland in staat:
for bezirk in bundesland:
for landkreis in bezirk:
landkreis.gewinn = landkreis.einnahmen - landkreis.ausgaben
Die einfachste Art, Iterierbarkeit zu erreichen, ist enweder von einer Klasse zu erben, die diese Funktionalität bereits hat (Mengen, Listen, Tupel, ...) oder die
__iter__()-Methode zu implementieren:
Code: Alles auswählen
>>> class MyIterable:
... def __iter__(self):
... for each in 'xyz':
... yield each
...
>>> mi = MyIterable()
>>> for c in mi:
... print(c)
...
x
y
z
Strings sind übrigens nicht-mutierbare Sequenzen von Buchstaben. Man kann direkt über sie iterieren, aber sie sind unveränderlich.
Vielleicht noch das: Wenn man anfängt Python zu lernen und schon Sprachen wie Pascal, C/C++ oder Java kennt, ist es wichtig, dass man sich klar macht, dass Python viel mehr Verwandschaft mit Lisp hat, als mit den genannten Sprachen.
In specifications, Murphy's Law supersedes Ohm's.