Ich möchte es auch nochmal versuchen
Also, alles in Python sind Objekte. Objekte können an Namen gebunden sein und Attribute haben. An diese Attribute (auch wieder Objekte) kommt man mit dem Punkt-Operator heran:
Hier wird erst das `person` Objekt gesucht und "in" diesem Objekt dann das Attribut `name`. Was wahrscheinlich eine Zeichenkette ist. Zeichenketten haben auch wieder Attribute, zum Beispiel eine Methode, die eine Zeichenkette mit dem gleichen Inhalt, aber in Grossbuchstaben zurückgibt und diese Methode heisst `upper`:
Code: Alles auswählen
In [5]: print person.name.upper
<built-in method upper of str object at 0x404b7660>
Huch, was ist nun passiert? Naja wir haben die Methode nicht aufgerufen, sondern die Methode selbst ausgegeben. Funktionen und Methoden sind auch nur Objekte und so sieht eine Methode aus, wenn man sie als Zeichenkette ausgibt. Also noch die Klammern ans Ende geschrieben, damit sie auch aufgerufen wird:
So, nun zum `self`. Methoden unterscheiden sich durch Funktionen dadurch, das sie an Objekte gebunden sind, genauer gesagt an Instanz-Objekte von Klassen. Das bedeutet nichts weiter als das ein Objekt weiss von welcher Klasse es ist und bei einem Methodenaufruf auf einem Objekt wird die Methode in der Klasse aufgerufen, wo sie nur eine Funktion ist, mit dem Objekt selbst als erstem Parameter.
Kleines Beispiel:
Code: Alles auswählen
class Person:
def __init__(self, name, surname):
self.name = name
self.surname = surname
def speak(self):
print 'Hello, my name is %s %s.' % (self.name, self.surname)
agent = Person('James', 'Bond')
agent.speak()
Person.speak(agent)
Die beiden letzten Zeilen sind äquivalent. Da das Objekt weiss von welcher Klasse es eine Instanz ist, wird in beiden Fällen die Funktion `Person.speak()` aufgerufen. Der Unterschied und Vorteil der ersten Variante ist, das der Programmierer an der Stelle nicht wissen muss, das es sich um ein `Person` Objekt handelt und das man den ersten Parameter nicht selbst übergeben muss.
Das man als Programmierer nicht die genaue Klasse wissen muss, erlaubt "Polymorphie", d.h. das man veschiedene Klassen mit dem gleichen Code benutzen kann. Mal angenommen man definiert noch eine Haustierklasse die auch "sprechen" kann:
Code: Alles auswählen
class Pet:
def __init__(self, name, sound):
self.name = name
self.sound = sound
def speak(self):
print '*%s*' % self.sound
dog = Pet('Lassie', 'wuff')
dog.speak()
Dann funktioniert folgender Quelltext nicht:
Wenn der Hund eingesetzt wird, dann kommt es zu einem `TypeError`:
Code: Alles auswählen
TypeError: unbound method speak() must be called with Person
instance as first argument (got Pet instance instead)
Wenn man das `creature` selbst entscheiden lässt, ob `Person.speak()` oder `Pet.speak()` benutzt werden soll, dann klappts: