Seite 1 von 2
Fragen zu Klassen
Verfasst: Dienstag 14. August 2007, 12:12
von Markus12
Hi,
ich habe mich nun mit Klassen beschäftigt und habe einige Fragen
1. Was bringt das hier: "class Klasse1(object):" Was heißt das "object"?
2. Wann kann man das "object" weggelassen?
3. Bei Attributen kann man da das "self." weglassen?
4. Was bringt das self generell?
5. Frage zu folgendem Code:
Code: Alles auswählen
class Klasse1(object):
wechselkurs=0.5
def __init__(self):
...
Was bringt es, wenn man eine Variable vor dem Initalisieren definiert?!
Danke schonmal!

Verfasst: Dienstag 14. August 2007, 12:40
von BlackJack
1. `object` ist hier die Basisklasse. Damit ist `Klasse1` automatisch eine "new style"-Klasse. Ohne würden zum Beispiel "properties" nicht funktionieren. In der Regel sollte man "new style" Klassen benutzen.
2. Das `object` kann man immer weglassen, wenn man eine "old style" Klasse haben möchte. "Früher" wollte man das bei Ausnahmen, weil das keine "new style" Klassen sein durften. Hat sich mittlerweile geändert.
3. Nein das `self` kann man nicht weglassen. Wie sollte man sonst Attribute von lokalen Namen unterscheiden!?
4. An `self` ist das Objekt gebunden auf dem die Methode aufgerufen wurde.
5. `wechselkurs` ist ein Klassenattribut, d.h. das teilen sich alle Klassen.
Re: Fragen zu Klassen
Verfasst: Dienstag 14. August 2007, 12:49
von EnTeQuAk
Markus12 hat geschrieben:Hi,
ich habe mich nun mit Klassen beschäftigt und habe einige Fragen
Sehr schön, auf gehts!
1. Was bringt das hier: "class Klasse1(object):" Was heißt das "object"?
Schwer zu erklären. Jedes Objekt erbt im enddefekt von dem Objekt
.
Wie das genau hinter den Kullissen abläft sollte vielleicht eine vertrautere Person beschreiben.
2. Wann kann man das "object" weggelassen?
Ja. Die Klassen, die mit von 'object' erben, werden [wiki]New-Style Klassen[/wiki]genannt.
3. Bei Attributen kann man da das "self." weglassen?
Wenn du innerhalb einer Klasse darauf zugreifst:
Code: Alles auswählen
class MyClass(object):
def __init__(self):
self.text = "Hallo"
def print(self):
return self.text
Nein. Denn 'self' ist eine Referenz auf die aktuelle Klasseninstanz.
Bedeutet, dass 'self.text' synonym zu 'MyClass.text' ist.
Wo du nun auch ungefair siehst, wofür 'self' steht.
4. Was bringt das self generell?
Siehe oben
Das sind so die Dinge, die ich sagen kann.
Ich denke, das andere, wie birkenfeld, Leonidas, gerold oder BlackJack oder wie unsere Meißter hier alle heißen sicherlich mehr zu dem Thema sagen können.
MfG EnTeQuAk
€dit: mist, zu langsam...
Verfasst: Dienstag 14. August 2007, 13:01
von Markus12
Erstmal Danke
Zu 3.:
Meinst du das Unterscheiden von lokalen Namen im Programmlauf selber? Ja, das wäre dann klar!
Zu 5.:
Heißt das, dass wenn ich jetzt eine Unterklasse "Klasse2" definieren würde und als Oberklasse "Klasse1" angeben würde (also Klasse2 erbt alle Attribut und Methoden von Klasse1 oder?), dass ich dann in Klasse2 auf das Klassenattribut "wechselkurs" zugreifen könnte, womöglich auch verändern?
Dann noch zu Properties -.-
Das habe ich nicht verstanden, was es mit Properties auf sich hat. Ich weiß, dass es hier um die Lese- und Schreibemethode geht. Aber generell kann man die Properties doch weglassen oder?
Ich hab hier in meinem Buch nachgelesen, dass, wenn man das zweite Argument weglaässt, dass man dann das Attribut einlesen, aber nicht verändern kann!
Und da man stark private Attribute ja trotzdem ändern kann, indem man z.B. schreibt: Klasse1()._Klasse1__attribut=...
dann kann man das ja ändern! Und so mit den Properties geht das nicht mehr, wenn das zweite Argument fehlt.
Liege ich damit richtig?
Danke!
Verfasst: Dienstag 14. August 2007, 13:23
von Markus12
Vielen Danke auch an dich, EnTeQuAk!

Das, was self bedeutet, war mir eig. klar. Aber zur Sicherheit und Überprüfung habe ich einfach nochmal nachgefragt
Aber zu deinem synonym:
müsste das nicht 'MyClass
().text heißen? Denn das Atrribut self.text gibts doch erst nach der Initialisierung oder? Wenn ich das richtig verstanden habe^^
Danke an euch beide

Verfasst: Dienstag 14. August 2007, 14:01
von EnTeQuAk
Aber zu deinem synonym:
müsste das nicht 'MyClass().text heißen? Denn das Atrribut self.text gibts doch erst nach der Initialisierung oder? Wenn ich das richtig verstanden habe^^
Was durchaus richtig ist. Da war mein Kopf wohl schon zwei Klammern weiter als meine Finger.
Heißt das, dass wenn ich jetzt eine Unterklasse "Klasse2" definieren würde und als Oberklasse "Klasse1" angeben würde (also Klasse2 erbt alle Attribut und Methoden von Klasse1 oder?), dass ich dann in Klasse2 auf das Klassenattribut "wechselkurs" zugreifen könnte, womöglich auch verändern?
gut erkannt.
Es gibt aber einen Unterschied, zu normalen Attributen und Klassenattributen.
Wir gehen mal davon aus, das wir folgende Basisklasse haben:
Code: Alles auswählen
>>> class Base(object):
... test = "test"
... def __init__(self):
... self.hammer = "hammer"
Wenn wir nun folgende 'sub' Klasse definieren:
Also eine, die absolut gar nichts macht, sind alle Attribute, sowohl das Klassenattribut 'test' als auch das Attribut 'hammer' weiterhin verfügbar.
Weiter gehts:
Code: Alles auswählen
class Sub(Base):
def __init__(self):
self.my_new_var = "lalala"
Versuche mal bei dieser Klasse, auf das Attribut 'hammer' zuzugreifen. Es wird nicht gehen, da die __init__ Methode überschrieben wurde und das Attribut 'hammer' *nicht* initialisiert wurde.
Was allerdings weiterhin geht, ist der Zugriff auf 'test'.
Klassenattribute können afaik nur geändert werden, nicht aber (wie oben zu sehen) gelöscht/entfernt/überschrieben werden.
MfG EnTeQuAk
Verfasst: Dienstag 14. August 2007, 14:17
von Markus12
Es hat sich auf jeden Fall gelohnt hier im Forum nachzuhacken

Danke vielmals. Jetzt ist einiges klarer!
Nochmal zu den Klassenattributen:
Ist das evtl. also ein Problem, wenn man im Programmlauf eine Varible definiert vor der Instanzierung der Klasse, die genauso heißt wie ein Klassenattribut?
Also, im Klartext:
Wenn ich im Prgrammlauf eine variable 'test' definieren würde und dann die Klasse 'Base' aufrufe, dass dann die lokale Variable überschrieben wird?
Verfasst: Dienstag 14. August 2007, 14:24
von EnTeQuAk
Nein, denn deine Variable 'test' ist auch unter dem Namen 'test' zu erreichen.
(Klassen-)Attribute sind unter 'Klasse.attribut' zu erreichen.
Und
ist ganz was anderes, als
.
MfG EnTeQuAk
Verfasst: Dienstag 14. August 2007, 14:29
von Markus12
Ja, ich hab das gerade in der Pyhon-Shell ausprobiert und woltle auch gerade mich verbessern
Das Klassenattirbut muss nämlich mit dem Klassennahmen davor aufgerufen werden. Aber diesmal hast du wieder einen Fehler drin, denn diesmal wird die Klasse nicht initialisiert!
Hier also:
Aber das war bestimmt nur ein Denkfehler. Ich bin froh, dass andere, die sich besser mit Python auskennen, anderen helfen!
So jetzt ists klar

Verfasst: Dienstag 14. August 2007, 15:46
von Markus12
Und nochmal eine grundlegende Frage!
Ich habe für ein Programm zwei Klassen. Die erste vererbt alles der zweiten.
Die erste hat eine __init__ - Methode, die zweite Klasse aber nicht, weil sie nur aus statischen Methoden besteht.
Ich habe dazu noch ein Klassenattribut in der ersten Klasse definiert, dass aber in der zweiten Klasse nicht abgerufen werden kann.
Da meine Erklärung etwas kompliziert war, hier der Aufbau:
Code: Alles auswählen
class Klasse1(object):
attribut='...'
def __init__(self):
pass
class Klasse2(Klasse1):
def methode1():
return attribut
def methode2():
attribut='hallo'
methode1=staticmethod(methode1)
methode2=staticmethod(methode2)
Hängt das vielleicht daran, dass man ein Klassenattribut nicht ändern kann oder dass das mit den statischen Methoden zusammenhängt?
Danke schonmal

Verfasst: Dienstag 14. August 2007, 15:56
von Rebecca
Du musst es ueber self.attribut ansprechen. Also z.b.
Verfasst: Dienstag 14. August 2007, 16:19
von BlackJack
Was natürlich nicht mit den statischen Methoden geht, die kennen ja kein `self`.
Verfasst: Dienstag 14. August 2007, 16:31
von Rebecca
Hehe, ist auch wieder wahr.
Was mich anfangs irritiert hat, ist, dass Python einen Unterschied zwischen statischen Methoden und Klassenmethoden macht, und manchmal passiert es mir immer noch, dass ich da nicht dran denke.
Hier waere also eine Klassenmethode angebracht.
Verfasst: Dienstag 14. August 2007, 19:07
von Joghurt
Markus12 hat geschrieben:Die erste hat eine __init__ - Methode, die zweite Klasse aber nicht, weil sie nur aus statischen Methoden besteht.
Dann versuchst du, Java in Python zu schreiben
Eine Klasse, die nur aus statischen Methoden besteht, macht keinen/wenig Sinn, in Java ist es aber notwendig, da es nur Klassen gibt.
Die "pythonische Lösung" wäre, die Funktionen in ein eigenes Modul zu packen, also z. B.
Vorher:
Code: Alles auswählen
# Datei1.py
class Foo(object):
... #normale Klasse
class Bar(object):
@staticmethod
def baz():
print "Hallo, Welt"
Jetzt löscht du Bar aus Datei1 und legst eine Datei bar.py an, mit dem Inhalt:
Dann legst du im selben Verzeichnis noch eine leere Datei namens "__init__.py" an, und dann kannst du mit baz arbeiten:
Code: Alles auswählen
# Möglichkeit 1
import bar
bar.baz() # Hallo Welt
# Möglichkeit 2
from bar import baz
baz() # Hallo, Welt
Verfasst: Dienstag 14. August 2007, 20:00
von Markus12
Danke, aber so schwer wollte ich das nicht machen

Ich will EIN Script, das übersichtlich sein soll, indem Zusatzfunktionen in einer extra Klasse deponiert sind
Ich könnte es auch in eine Klasse schreiben, aber dadurch wird es eben unübersichtlich und zu einfach und langweilig -.-
Weiß jemand noch eine andere Lösung, ohne irgendwas zu importieren, eine andere Datei anlegen zu müssen, oder es unnötig kompliziert zu machen? ^^
Verfasst: Dienstag 14. August 2007, 20:30
von Rebecca
Also entweder es sind so viele Funktionen, dass sich dafuer eigene Module lohnen, oder man laesst die Funktionen als Top-Level-Funktionen im Script.
Meine Meinung.
Verfasst: Mittwoch 15. August 2007, 09:58
von BlackJack
@Markus12: IMHO sind Klassen die nur aus statischen Methoden bestehen ein Missbrauch von Klassen. Die vorgesehene Einheit zum organisieren von Funktion ist nunmal das Modul. Statische Methoden, oder noch besser Klassenmethoden, sollten sich auf alternative "Konstruktoren" und Funktionen beschränken, die wirklich *ganz* eng mit einer Klasse verbunden sind.
Verfasst: Mittwoch 15. August 2007, 12:21
von gerold
BlackJack hat geschrieben:IMHO sind Klassen die nur aus statischen Methoden bestehen ein Missbrauch von Klassen.
Hallo BlackJack!
Ich habe den Thread nicht gelesen. Ich beziehe mich hier nur auf oben gezeigt Aussage.
Klassen eignen sich hervorragend auch zum Gruppieren von **zusammengehörenden** Funktionen. Ich mache das zwar recht selten, aber nur weil du das ablehnst fällt es mir trotzdem nicht im Traum ein, diese Art der Quellcodeorganisation von vorneherein abzulehnen.
Was ich damit sagen will? Ich glaube, dass du da ein wenig zu engstirnig denkst.
Namespaces are one honking great idea -- let's do more of those!
Wie kann man noch einfacher Namespaces erstellen, als mit Klassen? Nein, Module sind es sicher nicht. Ein Programm in *einem* Modul ist meistens einfacher als ein Programm in vielen Modulen.
lg
Gerold

Verfasst: Mittwoch 15. August 2007, 13:41
von Markus12
Ja, genau so wollte ich das auch machen. Ein Programm aus mehreren Klassen.
Verfasst: Mittwoch 15. August 2007, 15:35
von BlackJack
@gerold: Das Klassen nicht als Namensraum für Funktionen gedacht sind, sieht man ja schon daran, dass man sie besonders behandeln muss (`staticmethod()`) damit das überhaupt funktioniert.
Das kann man natürlich machen, genauso wie man eine Datei pro Klasse benutzen kann, oder ähnliches. Ich finde es schlechten Stil. Wenn es soviele Funktionen in einem Modul gibt, dass man die sinnvoll gruppieren kann bzw. muss um den Überblick zu behalten, ist es IMHO Zeit das Ganze zu refaktorisieren.