self.__init__

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
Newbie0000

Hi
Kann mir jemand die befehle self __init__
und die anderen __ befehle besser erklären.
DANKE
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hi Newbie0000,

self.__init__(...) dient zur Initialisierung von Klasseninstanzen. Wie alle Methoden, die mit "__" beginnen und enden, wird diese nicht direkt aufgerufen sondern beim erzeugen einer Instanz einer Klasse pythonintern verwendet.

Code: Alles auswählen

>>> class Test:
...     def __init__(self):
...         print "__init__ erledigt!"
...
 
>>> t = Test()
__init__ erledigt!
Da es eine Ganze Menge von __Methoden__ gibt, muss ich hier auf die Dokumentation 3.3 Special method names verweisen, da sonst mein Posting wirklich zu lang werden würde.

Wenn Du zu bestimmten __Methoden__ fragen hast, kannst Du aber gerne hier fragen.


Gruß

Dookie
newbie0000

danke ,aber könntest du das noch ein bisschen besser erklären
das mit self ,mit einpaar beispielen ,ich bin totaler anfänger in sachen OOP
DANKE
:)
Gast

hallo

self steht für die entsprechende instanz bzw. das konkrte objekt einer klasse.
im bsp. von dookie ist also t ein konkretes objekt bzw. eine instanz der klasse test.
klassen sind ansich baupläne.
t wurde nach diesem bauplan konstruiert. genau dafür ist übrigens die methode __init__(self) , auch konstruktor genannt, zuständig. alles was du in diese methode reinschreibst wird bei erzeugung eines konkreten objektes bzw. einer konkreten instanz ausgeführt. auch wert zuweisungen an attribute.

ich hoffe es hilft dir weiter.

mfg rolgal
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Ich versuche mal ein anschauliches Beispiel zu erläutern. Du bist eine Instanz der Klasse Mensch. Als Deine Eltern sich mal ganz lieb hatten, erzeugten sie eine neue Instanz von Mensch, Dich.
Objekte der Klasse Mensch haben auch eine __init__Methode, Dies ist die Schwangerschaft. Hier bekommt der Mensch seine Attribute wie: Geschlecht, Hautfarbe, Haarfarbe, Augenfarbe, Gewicht, Grösse ...
"self" heisst bei Menschobjekten "ich". Hier kann ich auch gleich ein grosses allgemeines Missverständnis in der Programmierung versuchen aufzuklären. Wenn Du einer Variablen ein Objekt zuweisst, ist die Variable nicht das Objekt selber, sondern nur ein Verweis darauf. Also z.B. hier im Forum gibt es einen User "newbee0000" Draussen in der Welt heisst Du vielleicht "Michael" und wenn Du zu einem Amt gehst, bekommst Du eine Nummer z.B. "12345" und für dich selber bist du "ich". Wenn jetzt "Michael" angewiesen wird, zum Friseur zu gehen, Michel.gehe_zum_friseur(welcher=der_ums_eck) dann wird die Methode "gehe_zum_friseur" der Klasse Mensch aufgerufen und bekommt die Parameter iself=ch welcher=der_ums_eck. Hier im Forum würde newbee2000.gehe_zum_friseur(welcher=der_ums_eck) zum gleichen Ergebnis führen.
Eine sehr gute Einführung zu Python und OOP findest Du auf Programmieren lernen Speziell zu OOP und der sache mit dem self unter Objektorientierte Programmierung

Gruß

Dookie
Gast

@dookie

es müßte dann in meiner erklärung lauten: t ist ein verweis auf ein objekt der klasse test.
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

@ rolgal,

genau, man kann sich t auch als Behälter vorstellen. Wie ein Eimer oder eine Flasche oder eint Tüte auf der ein "t" aufgemahlt ist. Diese Behältnisse können dann z.B. Wasser enthalten. Das Wasser ist dann das eigentliche Objekt. Es gibt dann auch Objekte, die ihrerseits Verweise auf Objekte enthalten können. Wie z.B. Listen oder Dictionaries. Das ist eben einer der Vorteile von OOP, aber auch gerade wenn man schon Procedurale Programmierung kennt, am Anfang oft schwer zu durchschauen.
Du kannst ja auch schreiben k = t hier wird dann nicht das Objekt auf das t verweist kopiert, sondern der Verweis auf das Objekt wird kopiert. Wenn Du jetzt den Inhalt von t änderst, also z.B. ein Attribut änderst, zeigt auch k weiterhin auf das gleiche Objekt dessen Attribut nun geändert ist.


Gruß

Dookie
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Nochmal ich,

vergesst die Behälter, stellt euch Variablen eher als kleine Merkzettelchen vor, und den Speicher des Komputers als Setzkasten. Jedes Fach im Setzkasten hat eine Nummer (Speicheradresse). Der Pythoninterpreter schaut dann auf dem Zettelchen t wo im Setzkasten das entsprechende Objekt liegt.


Gruß

Dookie
DER Olf
User
Beiträge: 283
Registriert: Mittwoch 24. Dezember 2003, 19:32

hey! jetzt hab ich das auch mal verstanden! :D is gar nicht mal so schwer...
ich hab das bei "lerning to programm" nicht wirklick verstanden, aber was ihr hier gepostet habt... :wink: :wink: :wink:
newbie0000

Hi

Danke dookie und rolgal.

Jetzt hab ichs bisschen besser verstanden :)

Noch eine frage,der code ist aus dem Tut vom

Alan Gauld



class Meldung:

def __init__(self, einString):

self.text = einString

def druckEs(self):

print self.text



m1 = Meldung("Hallo Welt")

m2 = Meldung("Tschüss, es war kurz aber süss")



notiz = [m1, m2] # bringt die Objekte in eine Liste

for msg in notiz:

msg.druckEs() # druckt jede Meldung sofort aus





Warum steht beim druckEs auch self und

warum muss man print self.text und nicht

einfach print einString

und die letzte frage für heute.

wie kann msg auf druckEs zugreifen

es wurde ja nirgendwo eine instanz erstellt

msg = Meldung() oder????



p.s. sorry wenn ich euch langweile mit den fragen,

aber ich würde so gerne Python lernen :-)



www.linux.hr
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Hallo,

erstmal wenn Du code postest, schliesse diesen auch in <code>...</code> (statt < und > verwende [ und ]) ein, dann bleiben auch die, gerade bei Python wichtigen, Einrückungen erhalten.
Ich hab hier das Beispiel nochmal dokumentiert

Code: Alles auswählen

class Meldung:

    def __init__(self, einString): # Jede Instanz bekommt einen String
        self.text = einString # ich merke mir den Verweis auf den String im Attribut text

    def druckEs(self): # Schreibe den String
        print self.text # ausgabe des Strings auf den das Attribut text zeigt

#---fertig mit der Klassendefinition


m1 = Meldung("Hallo Welt") # erzeuge Instanz
m2 = Meldung("Tschüss, es war kurz aber süss") # und noch eine


notiz = [m1, m2] # bringt die Objekte (eigentlich Verweise auf Objekte) in eine Liste

for msg in notiz: # hole dir nacheinander alle Verweise
    msg.druckEs() # druckt jede Meldung sofort aus
So nun zu Deinen Fragen:
Warum steht beim druckEs auch self
druckEs ist wie auch __init__ eine Methode des Objekts der Klasse Meldung. Solche Methoden bekommen immer als ersten Parameter self, dies ist der Verweis (ein Zettelchen mit der Adresse) auf das Objekt selbst. Dadurch kann dann in druckEs auf den Eintrag in self.text zugegriffen werden.
warum muss man print self.text und nicht einfach print einString
einString, war nur ein Zettelchen für __init__, das wurde mit dem Beenden von __init__ in den Converter geschmissen. Aber vorher wurde die Adresse die draufstand ja in __init__ mit self.text = einString geschrieben.
und die letzte frage für heute.
wie kann msg auf druckEs zugreifen es wurde ja nirgendwo eine instanz erstellt
msg = Meldung() oder????
Doch es wurden sogar 2 Instanzen erstellt

Code: Alles auswählen

m1 = Meldung("Hallo Welt")
m2 = Meldung("Tschüss, es war kurz aber süss") 
Meldung("Hallo Welt") erstellt eine Instanz. Die Anweisung m1 = Meldung("Hallo Welt") bedeutet für den Interpreter, erstelle eine Instanz von Meldung. Der Interpreter sagt der Klasse Meldung: "Hallo Klasse Meldung, ich brauch eine Instanz von Dir mit dem String 'Hallo Welt" als Parameter. Die Klasse gibt dann dem Interpreter die Adresse der neuen Instanz zurück und der Interpreter schreibt sich die Adresse auf das Zettelchen m1. Das gleiche passiert dann nochmal, allerdings mit dem String ""Tschüss, es war kurz aber süss" als Parameter und der Interpreter schreibt sich die Adresse, die ihm die Klasse für die zweite Inszanz liefert, auf den Zettel m2.
Wie kann nun msg auf druckEs zugreifen? msg ist wieder nur ein Zettelchen. Zuvor wurd ja eine Liste erstellt, die kannst Du dir als Block vorstellen. Also viele Zettelchen wo Adressen von Objekten(Instanzen) abgelegt sein können. Das erledigte die Anweisung notiz = [m1, m2]. Das erzeut eine Liste mit den Verweisen auf die Instanzen auf die m1 und m2 zeigen.
for msg in notiz: bedeutet, hol dir aus der Liste, deren Adresse auf dem Zettelchen "notiz" steht, jeden Eintrag (also die Adressen der Objekte (Instanzen) auf die auch m1 und m2 zeigen) und schreib ihn auf den Zettel msg. Im Gegensatz zu echten Zetteln, kann man die variablen wie msg auch überschreiben, dabei geht der alte Inhalt verloren und wird durch den neuen ersetzt. So zeigt msg beim ersten mal auf die Instanz auf die auch m1 zeigt, und beim zweiten Mal auf die Instanz auf die m2 zeigt.
Jetzt dürfte klar sein, wie msg.druckEs() funktioniert. msg ist eben kein Objekt, sonder nur der Verweis auf das Objekt. Da druckEs eine Methode ist, bekommt sie als ersten Parameter auch einen Verweis auf sich selber auf dem Zettelchen self, es gibt ja mehr Objekte der Klasse Meldung, die sich die Methode druckEs teilen. Der Interpreter schreibt die Adresse die auf dem Zettelchen msg steht auf das zettelchen self, das an die Methode printEs übergeben wird. So kann druckEs die Attribute von der Instanz deren Adresse auf self steht verwenden. in dem Fall das Attribut "text" und den String, auf den self.text zeigt ausgeben.


Gruß

Dookie
NOTZE
User
Beiträge: 106
Registriert: Mittwoch 21. Januar 2004, 20:28

@ Dookie
Also ich muss sagen klasse erklärt ich hab auch schon learnign to program angeugckt und hab es verstanden aber deine beiden erklärungen
waren echt gut zu durchblicken
:P :P :P :P
Antworten