Datentypen und Variablen
Einführung
Auch wenn man Variablen und Datentypen von anderen Programmiersprachen bereits zur Genüge zu kennen glaubt, sollte man dieses Kapitel dennoch zumindest überfliegen, denn einiges ist eben doch anders in Python.Variablen
Eine Variable im allgemeinsten Sinne ist einfach ein Behälter (Container) zur
Aufbewahrung von bestimmten Werten, also z.B. Strings oder Zahlen. Man kann im
Verlauf des Programms auf diese Variablen, oder genauer auf den Wert ihres Inhaltes
zugreifen, oder ihnen einen neuen Wert zuweisen.
In den meisten Programmiersprachen, wie z.B. C, ist es so, dass eine
Variable einen festen Speicherplatz bezeichnet, in dem Werte eines bestimmten
Datentyps abgelegt werden können. Während des Programmlaufes kann sich der
Wert der Variable ändern, aber die Wertänderungen müssen vom gleichen Typ
sein. Also man kann nicht in einer Variable zu einem bestimmten Zeitpunkt eine
Integerzahl gespeichert haben und dann diesen Wert durch eine Fließkommazahl
überschreiben. Ebenso ist der Speicherort der Variablen während des gesamten
Laufes konstant, kann also nicht mehr geändert werden. In Sprachen wie C wird
der Speicherort bereit durch den Compiler fixiert.
In Python sieht dies anders aus. Zunächst einmal bezeichnen Variablen in
Python keinen bestimmten Typ und deshalb benötigt man auch in Python keine
Typdeklaration. Benötigt man im Programm bespielsweise eine Variable i mit dem
Wert 42, so erreicht man dies einfach mit der folgenden Anweisung:
i = 42Obige Anweisung darf man nicht als mathematisches Gleichheitszeichen sehen, sondern als "der Variablen i wird der Wert 42 zugewiesen", d.h. der Inhalt von i ist nach der Zuweisung 42. Man kann diesen Wert der Variablen auch, wie man im folgenden Beispiel sieht, anschließend ändern:
>>> i = 42 >>> i = i + 1 >>> print i 43 >>>
Zahlen
Python kennt vier eingebaute (built-in) Datentypen für Zahlen:
- Ganzzahl (Integer)
z.B. 4321
vorangestellte 0 bedeutet Oktalzahl und
vorangestelltes 0x bedeutet Hexzahl
- lange Ganzzahl
Sie können beliebig lang werden
Sie werden mit einem l am Anfang bzw. L am Ende bezeichnet.
- Fließkommazahlen
Zahlen der Form 3.14159 oder 17.3e+02
- komplexe Zahlen
z.B. 1.2+3j
Strings
Ein String, oder Zeichenkette, kann man als eine Sequenz von einzelnen Zeichen sehen.
Jedes einzelne Zeichen eines Strings, kann über einen Index angesprochen werden.
Im folgenden Beispiel sehen wir, wie der obige im Bild dargestellt String in Python
definiert wird und wie wir auf ihn zugreifen können:
>>> s = "Python" >>> print s[0] P >>> print s[3] hDie Länge eines Strings kann man mit der Funktion len() bestimmen und damit kann man auch einfach beispielsweise auf das letzte oder vorletzte Zeichen eines Strings zugreifen:
>>> s = "Python" >>> index_last_char = len(s) - 1 >>> print s[index_last_char] n >>> print s[index_last_char - 1] o >>>Da es bei der praktischen Arbeit sehr häufig vorkommt, dass man auf einzelne Zeichen eines Strings von hinten zugreifen muss, wäre es sehr lästig, wenn man dies immer über den Umweg durch den Aufruf der Funktion len() machen müsste. Python bietet deshalb eine elegantere Möglichkeiten. Die Indices werden auch von rechts durch negative Indices nummeriert, d.h. das letzte Zeichen wird mittels des Index -1, das vorletzte mittels -2 usw. angesprochen. Wir sehen dies in der folgenden Abbildung veranschaulicht:
Im Code sieht das wie folgt aus:
>>> s = "Python" >>> last_character = s[-1] >>> print last_character n
Strings können unter Benutzung von
- einzelnen Anführungszeichen (')
'Dies ist ein String mit einfachen Quotes' - doppelten Anführungszeichen (")
"Mayers' Dackel heißt Waldi" - dreifachen Anführungszeichen (''') oder (""")
'''String in dreifachen Anführungszeichen können auch über mehrere Zeilen gehen und 'einfache' und "doppelte" Anf.zeichen enthalten.'''
Wichtige Stringfunktionen
Ein paar String-Funktionen:- Konkatenation (englisch: Concatenation)
Diese Funktion dient dazu mittels des "+"-Operators zwei Strings zu einem neuen String zusammenzuhängen:
"Hello" + "World" -> "HelloWorld" - Wiederholung (englisch: Repetition)
Ein String kann wiederholt konkateniert werden. Dazu benutzt man den "*"-Operator.
Beispiel:
"*-*" * 3 wird zu "*-**-**-*" - Indexing
"Python"[0] -> "P" - Slicing
Das englische Verb "to slice" bedeutet in Deutsch "schneiden" oder auch "in Scheiben schneiden". Letztere Bedeutung entspricht auch der Funktion von Slicing in Python. Man schneidet sich gewissermaßen eine "Scheibe" aus einem String heraus. [2:4] bedeutet im folgenden Ausdruck, dass wir aus dem String "Python" einen Teilstring herausschneiden, der mit dem Zeichen des Index 2 (inklusive) beginnt und bis zum Index 4 (exklusive) geht:
"Python"[2:4] -> "th"
- Länge eines Strings
len("Python") -> 6
Unveränderliche Zeichenketten
Wie in Java aber nicht wie in C oder C++, können Strings in Python nicht verändert werden. Versucht man eine indizierte Position zu ändern, erzeugt man eine Fehlermeldung:>>> s = "Some things are immutable!" >>> s[-1] = "." Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'str' object does not support item assignment >>>
Escape- oder Fluchtzeichen
Es gibt Zeichenfolgen, die den Textfluss steuern, wie zum Beispiel ein Newline (Zeilenvorschub) oder Tabulator. Sie lassen sich nicht auf dem Bildschirm als einzelne Zeichen darstellen. Die Darstellung solcher Zeichen innerhalb von String-Literalen erfolgt mittels spezieller Zeichenfolgen, sogenannter Escape-Sequenzen. Eine Escape-Sequenz wird von einem Backslash \ eingeleitet, gefolgt von der Kennung des gewünschten Sonderzeichens. Übersicht der Escape-Zeichen:- \ Zeilenfortsetzung
- \\ Rückwärtsschrägstrich
- \' Einzelnes Anführungszeichen
- \" Doppeltes Anführungszeichen
- \a Glocke
- \b Rückschritt
- \e Ausmaskieren
- \0 Null
- \n Zeilenvorschub (linefeed, LF)
- \v Vertikaler Tabulator
- \t Horizontaler Tabulator
- \r Wagenrücklauf (carriage return, CR)
- \f Seitenvorschub
- \0XX Oktaler Wert
- \xXX Hexadezimaler Wert
Beispiel:
r"\n bewirkt einen Zeilenvorschub"
Typwechsel bei Variablen
In Python kann eine Variable, wie bereits gesagt, sofort ohne Deklaration des Datentyps verwendet werden. Dennoch vergibt Python einen Datentyp, d.h. je nach Datentyp, wird die Variable anders angelegt, also als Integer, Float, String, und so weiter. Eigentlich müsste man sagen, dass eine Objekt mit einem bestimmten Datentyp bzw. Klasse angelegt wird. Die Variable referenziert dann dieses Objekt, d.h. die Variable selbst hat also eigentlich keinen Typ. Anders ausgedrücktDer Datentyp ist in Python nicht an die Variable, sondern an den Wert gebunden, was impliziert, dass sich der Typ zur Laufzeit ändern kann, wie wir im folgenden Beispiel sehen können:
i = 42 # Datentyp ist integer (implizit) i = 42 + 0.11 # Typ ändert sich zu float i = "fourty" # und jetzt ein String
Wechselnde Speicherorte
Prinzipiell wird sich im vorigen Fall, wobei das natürlich implementierungsabhängig ist, der Speicherort für die Variable i ändern. Der Interpreter kann bei der Anweisung "i = 42" den Wert als Integer abspeichern, muss aber bei der Anweisung "i = 42 + 0.11" einen neuen Ort für eine Float-Zahl anlegen. Für i = "fourty" muss er in einen String gewandelt werden.Achtung: Als Anwender braucht man dies eigentlich nicht zu wissen, da ja alles automatisch geschieht!
Betrachten wir nun folgenden Python-Code:
>>> x = 3 >>> y = x >>> y = 2
Intuitiv würde man davon ausgehen, dass Python zunächst für x einen Speicherort wählt und dort das Objekt (Zahl) 3 abspeichert. Anschließend wird der Variablen y der Wert von x zugewiesen. In C und vielen anderen Programmiersprachen würde auch für y ein eigener Speicherort bestehen, in dem nun die Zahl 3 hineingeschrieben würde. Python geht anders vor: x ist eine Variable mit dem Objekt 3 und y ist eine Variable mit dem "selben" (nicht "gleichen") Objekt. x und y "zeigen" auf das gleiche Objekt. In der letzten Zeile wird y nun der Wert 2 zugewiesen, jetzt muss ein neues Objekt angelegt werden und y "zeigt" auf einen neuen Speicherort. (Anm: Dieses eben verwendete "zeigen" sollte von C-Programmierern keinesfalls mit den unter C verwendeten Pointern verwechselt werden.)
Es stellt sich nun die Frage, wie man das oben gesagte überprüfen kann. Dazu bietet sich die Identitätsfuntion id() an. Die Identität einer Instanz dient dazu, sie von allen anderen Instanzen zu unterscheiden. Die Identität ist eine Ganzzahl, und sie ist innerhalb eines Programmes eindeutig. Die Identitätsfunktion id() liefert die Identität. So kann man prüfen, ob es sich um eine bestimmte Instanz handelt und nicht nur um eine mit dem gleichen Wert und Typ. Wir geben nochmals das obige Beispiel ein, lassen uns aber jeweils die Identität ausgeben:
>>> x = 3 >>> print id(x) 157379912 >>> y = x >>> print id(y) 157379912 >>> y = 2 >>> print id(y) 157379924 >>> print id(x) 157379912 >>>Wir stellen fest, dass sich die Identität erst ändert, nachdem wir y einen neuen Wert zugewiesen haben. Die Identität von x bleibt gleich, d.h. der Speicherort von x wird nicht geändert.
Besonderheiten bei Strings
Einen besonderen Effekt können wir bei Strings feststellen. Im folgenden Beispiel wollen wir dies veranschaulichen. Dazu benötigen wir noch den "is"-Operator. Sind a und b zwei Strings, dann prüft "a is b", ob a und b die gleiche Identität (Speicherort) haben. Wenn "a is b" gilt, dann gilt auch "a == b". Aber wenn "a == b" gilt, dann gilt natürlich nicht notwendigerweise auch "a is b"!Nun wollen wir untersuchen, wie Strings in Python abgespeichert werden. Im folgenden Beispiel, erkennen wir, dass a und b sich den gleichen Speicherort teilen, obwohl wir diesmal keine Zuweisung der Art "b = a" verwendet haben:
>>> a = "Linux" >>> b = "Linux" >>> a is b TrueWie sieht es jedoch aus, wenn der verwendete String länger ist? Im folgenden verwenden wir als String den längsten Ortsnamen der Welt. Eine Gemeinde mit etwas mehr als 3000 Einwohnern im Süden der Insel Anglesey in der gleichnamigen Grafschaft im Nordwesten von Wales:
>>> a = "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch" >>> b = "Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch" >>> a is b TrueAber Vorsicht ist geboten, denn was für eine Gemeinde in Wales funktioniert, schlägt beispielsweise für Baden-Württemberg fehl:
>>> a = "Baden-Württemberg" >>> b = "Baden-Württemberg" >>> a is b False >>> a == b TrueAlso an der geographischen Lage kann es nicht liegen, wie man im folgenden Beispiel sieht. Es sieht vielmehr so aus, als dürften keine Sonderzeichen oder Blanks im String vorkommen.
>>> a = "Baden!" >>> b = "Baden!" >>> a is b False >>> a = "Baden1" >>> b = "Baden1" >>> a is b True