6. Strings als Objekte

Strings sind in Python Objekte (Vorsicht! In Python vor 2.0 war das noch etwas anders, das Folgende stimmt für die mittlerweile antike Version 1.5 nicht).

Objekte enthalten neben Daten auch Funktionen, die dann Methoden heißen. Methodenaufrufe sehen wie Funktionsaufrufe aus:

>>> s = "Hallo"
>>> s.find("ll")
2

Zunächst kommt also das Objekt, dessen Methode verwendet werden soll (s), dann ein Punkt und dann der Name der Methode; find sucht im String nach einem anderen String und gibt dessen Position zurück. Der erste Buchstabe hat die Position 0 (!), ist der Suchstring nicht enthalten, wird -1 zurückgegeben.

>>> s.find("Ha")
0
>>> s.find("Ha!")
-1

Die -1, die find zurückgibt, wenn es den String nicht gefunden hat, ist etwas wie ein “magischer Wert” – etwas, das eine besondere und sozusagen verabredete Bedeutung über die eigentliche Interpretation des Wertes hinaus hat. In diesem Fall sagt es einfach: Die -1 ist nicht etwa eine Position, sondern eben etwas wie eine Fehlerkennung.

(Weiterführend:) In diesem Fall ist das nicht sehr schön; es wäre besser gewesen, wenn die Designer hier z.B. None zurück gegeben hätten, denn dann hätte man keine Magie gebraucht. In der Regel hat man in Python aber im Fehlerfall eine ganz andere Reaktion, es wird nämlich eine Exception ausgelöst. Ein Ersatz für find, der das tut, heißt index. Allerdings ist nicht ganz klar, dass die Abwesenheit eines Substrings in einem String wirklich ein “Fehler” ist, und so ist das Verhalten von find schon zu rechtfertigen. Aber das nur nebenbei.

Strings haben viele Methoden (vgl. Python-Referenz), etwa

  • count (zählt, wie oft ein String im anderen vorkommt)
  • lower, upper (wandelt alle Groß- in Kleinbuchstaben und umgekehrt)
  • replace (ersetzt Vorkommen eines Substrings durch einen anderen)

>>> s = "Labala"
>>> s.replace("a", "ug")
'Lugbuglug'
>>> s.count("la")
1
>>> s.lower()
'labala'
>>> s.lower().count("la")
2

Das letzte Beispiel zeigt: Das Ergebnis einer Funktion, die einen String zurückgibt, ist natürlich wieder ein Objekt mit Methoden.

(Weiterführend:) In der Tat sind in modernem Python eigentlich alle Werte in Wirklichkeit Objekte (immerhin nennt sich Python ja auch objektorientiert). Sogar Zahlen haben Methoden, die man allerdings aus syntaktischen Gründen (gegenwärtig) etwas ausbuddeln muss (der Punkt ist in Zahlen als Dezimaltrenner reserviert). So lässt sich etwa der Ausdruck 1+1 etwas verquast als

>>> (1).__add__(1)
2

schreiben. Warum das wie geht, ist vorerst nicht wichtig, es ist aber nützlich, die Vorstellung zu pflegen, dass die Anwendung von Operatoren und Funktionen auf Werte in Python meistens den Aufruf von Methoden der Operanden nach sich zieht.

In diesem Sinn ist auch die Behauptung von oben, len “frage” sein Argument nach seiner Länge zu verstehen – len versucht einfach, eine Methode namens __len__ in seinem Argument aufzurufen. Wenn ein Objekt diese Methode nicht hat, sagt len eben, das Objekt habe keine Größe (besser wäre vielleicht: Es kennt sie nicht).

Übungen zu diesem Abschnitt

Ihr solltet euch wenigstens an den rötlich unterlegten Aufgaben versuchen

(1)

Macht euch klar, dass Methoden zu ihren Objekten gehören. Es klingt vielleicht ein bisschen blöd, aber es ist keineswegs klar, dass die beiden “replaces” im folgenden Dialog (probiert ihn!) wirklich verschieden sind:

>>> s1 = "foo"
>>> s2 = "bar"
>>> s1.replace("o", "e")
>>> s2.replace("o", "e")

(2)

Die Methoden von Strings ändern nie den String selbst – sie geben neue Objekte zurück. Probiert folgendes und erklärt, was dabei passiert:

>>> s = "foo"
>>> s.replace("o", "e")
>>> print s
>>> s = s.replace("o", "e")
>>> print s

(3)

Den Unterschied zwischen Funktionen und Methoden kann man bei Strings besonders gut sehen, weil Python aus den Zeiten, als Strings noch keine Objekte waren, die meisten String-Methoden auch noch als Funktionen bereitstellt. Man muss dem Interpreter allerdings erst sagen, dass man sie verwenden will, und zwar mit der Anweisung from string import <methodenname> (wir werden später sehen, was das bedeutet). Probiert also folgendes:

>>> from string import replace
>>> "foo".replace("o", "e")
>>> replace("foo", "o", "e")

Ihr seht, dass, wie behauptet, ein Methodenaufruf sowas ist wie ein Funktionsaufruf, nur dass das Objekt, auf das die Methode angewandt wird, im ersten Argument der Funktion steht.

Mit anderen Klassen, deren Methoden nicht auch irgendwo als Funktionen stehen, lassen sich dennoch ähnliche Dinge tun. Wir werden das Äquivalent der replace-Funktion aus dem string-Modul später als “unbound method” kennenlernen.

(4)

Lest die Dokumentation zum String-Modul oder zum String-Typ. Ihr werdet vielleicht noch nicht so furchtbar viel verstehen, aber es ist wichtig, dass ihr wisst, wie ihr auf die Dokumentation zugreift. Häufig haben IDEs eingebaute Hilfen, was jedoch immer geht, ist ein Blättern in der Library Reference in HTML und, so euer Python ordentlich installiert ist, mit dem Kommandozeilenprogramm pydoc. Tippt einfach in ein Shellfenster pydoc str oder pydoc string.


Markus Demleitner

Copyright Notice