\section {Eingebaute Typen}
\label {typen}

  Python stellt eine Reihe mächtiger eingebauter Typen zur Verfügung.
  Objekte dieser Typen verhalten sich generell wie alle anderen Objekte
  auch. Jedoch existieren für die meisten dieser Typen
  Literalschreibweisen und ebenso existiert oft eine spezielle Syntax
  für gängige Operationen auf diesen Objekten (zum Beispiel für die
  Iteration über eine Liste). Doch auch hier greift das Prinzip des Duck
  Typing, denn viele Syntaxelemente sind nur Verschleierungen von
  Methodenaufrufen auf einem Objekt. Daher ist es möglich, das
  Verhalten von Instanzen eigener Klassen bei der Verwendung der
  Standardsyntax zu definieren (sogenanntes \emph {Operator
  Overloading}).
  
    \subsection {Zahlen}

      Python kennt von Haus aus verschiedene Arten von Zahlen. Eine
      Übersicht befindet sich in Tabelle~\ref {tab:zahlen}. Der
      Boolesche Typ ist in Python eine Unterklasse der Integers, daher
      taucht er in dieser Liste ebenfalls auf.
      
      \begin {table}
        \centering
        \begin {tabular}[tbp]{llr}
          \toprule
          \bf {Typ} & \bf {Werte} & \bf {Literal} \\
          \midrule
          \lstinline $<type 'bool'>$ & Wahrheitswerte
            & \lstinline $True$ \lstinline $False$ \\
          \lstinline $<type 'int'>$ & Ganze Zahlen
            & \lstinline $1$ \lstinline $23$ \lstinline $1024$\\
          \lstinline $<type 'long'>$ & beliebig große, ganze Zahlen
            & \lstinline $29846983214L$ \\
          \lstinline $<type 'float'>$ & Fließkommazahlen
            & \lstinline $27.2$ \\
          \lstinline $<type 'complex'>$ & Komplexe Zahlen
            & \lstinline $3.5+10.0j$ \\
          \bottomrule
        \end {tabular}
        \caption {Zahlentypen}
        \label {tab:zahlen}
      \end {table}

      Eine Besonderheit der Zahlentypen ist, dass ihre Instanzen
      unveränderbar (\emph {immutable}) sind. Alle arithmetischen
      Operationen erzeugen ein neues Objekt.  Dessen Typ wird möglichst
      "`eng"' ausgewählt, das heißt eine Addition von zwei Integers
      liefert einen neuen Integer, eine Addition von einem Integer und
      einer Fließkommazahl liefert eine eine Fließkommazahl (auch dann,
      wenn sie ganzzahlig "`aussieht"').  Eine vollständige Erklärung
      der zugrunde liegenden Regeln und der unterstützten Operationen
      befindet sich in \cite[Kapitel~2.3.4]{pylib}.
      
      \lstinputlisting[float=tb,caption=Methodenaufrufe für arithmetische
      Operationen,label=lst:arithmetik]{lst/arithmetic.py}
      
      Python benutzt die gängige Infixnotation für die meisten
      arithmetischen Operationen. Tatsächlich ruft der Interpreter aber
      wie erwähnt eine bestimmte Methode des Objekts auf. Zur
      Verdeutlichung ein Beispiel in Listing~\ref {lst:arithmetik}.
      
    \subsection {Sequenzen}
    \label {sequenzen}
    
      Python kennt einige vordefinierte Typen von Objektsequenzen. Die
      einfachsten sind \emph {Listen} und \emph {Tupel}. Beide können
      beliebig viele Objekte unterschiedlicher Typen aufnehmen und
      adressieren diese per Index, angefangen bei Null.\footnote
      {Negative Indizes anzugeben ist ebenfalls möglich. Der Index
      \lstinline$-1$ zeigt auf das letzte Objekt der Sequenz,
      \lstinline$-2$ auf das vorletzte und so weiter. Der angegebene
      Index wird allerdings \emph {nicht} modulo der Sequenzlänge
      benutzt, um Zugriffe auf nicht-existierende Elemente zu
      verhindern. Ein ungültiger Index erzeugt einen \lstinline
      $IndexError$.} Sie unterscheiden sich dadurch, dass Tupel
      immutable sind, während Listen veränderbar sind. Zeichenketten
      sind ebenfalls immutable.

      \begin {table}
        \centering
        \begin {tabular}[tbp]{llr}
          \toprule
          \bf {Typ} & \bf {Werte} & \bf {Literal} \\
          %\hline
          \midrule
          \lstinline $<type 'tuple'>$ & Statische Liste
            & \lstinline $(23, 'abc', obj)$ \\
          \lstinline $<type 'list'>$ & Veränderbare Liste
            & \lstinline $[23, 'abc', obj]$ \\
          \lstinline $<type 'str'>$ & Zeichenkette (statisch)
            & \lstinline $"abc"$ \lstinline $'abc'$
              \lstinline $"""abc"""$ \\
%          \lstinline $<type 'unicode'>$ & Zeichenkette in Unicode
%            & \lstinline $u"ab"$ \lstinline $u'ab'$
%              \lstinline $u"""ab"""$ \\
          \bottomrule
        \end {tabular}
        \caption {Sequenztypen (Auswahl)}
        \label {tab:sequenzen}
      \end {table}

      Die Literaldarstellungen der Sequenztypen sind in Tabelle~\ref
      {tab:sequenzen} dargestellt. Für Zeichenketten gibt es drei
      verschiedene Darstellungen, wobei zwischen den Schreibweisen mit
      einfachen und doppelten Anführungszeichen nicht unterschieden
      wird. Sie erlauben nur, das jeweils andere Anführungszeichen in
      der Zeichenkette selbst zu benutzen. Die Variante mit drei
      doppelten Anführungszeichen erlaubt zudem Zeilenumbrüche innerhalb
      der Zeichenkette.

      Operationen auf den Sequenztypen sind detailliert in
      \citep[Kapitel~2.3.6]{pylib} beschrieben und können
      selbstverständlich von eigenen Typen (sofern semantisch sinnvoll)
      nachgeahmt werden.

    \subsection {Mappings}

      Zur Zeit gibt es nur einen einzigen eingebauten Mappingtyp in
      Python -- das Dictionary. Dictionaries verhalten sich wie Listen,
      nur dass die enthaltenen Objekte (die \emph {Werte}) nicht über
      einen Index sondern über ein eindeutiges Objekt (den sog. \emph
      {Schlüssel}) angesprochen werden. Ein weiterer Unterschied ist,
      dass die Elemente in einem Dictionary ungeordnet vorliegen. Da
      Python ein Hashingverfahren verwendet, das eine (nahezu) konstante
      Zugriffszeit garantiert, müssen alle Schlüssel immutable sein. Die
      Werte können beliebige Objekte sein. Ein Beispiel für die
      Literalschreibweise und Verwendung von Dictionaries befindet sich
      in Listing~\vref {lst:dict}. Auch hier gilt wieder, dass der
      Aufruf einer Methode durch eine besondere Syntax verborgen wird.
      In diesem Fall ist es der Zugriff auf einen bestimmten Wert
      mittels eines Schlüssels (\lstinline $[key]$), der den Aufruf der
      Methode \lstinline $__getitem__(self, key)$ des Dictionaries
      auslöst.
      
      \lstinputlisting[float=tb,caption=Verwendung von
      Dictionaries,label=lst:dict]{lst/dict.py}
    
    \subsection {Weitere Typen}

      Wie schon angedeutet, gibt es natürlich auch Typen, die Module,
      Klassen, Methoden, Funktionen und Codeblöcke beschreiben. Der
      intensive Umgang mit Objekten dieser Typen ist recht selten. Man
      sollte aber im Hinterkopf behalten, dass auch solche Objekte
      herumgereicht werden können. Besonders in eventbasierten Systemen
      (etwa im GUI-Bereich) werden häufig Funktionen als sogenannte
      \emph {Callbacks} benutzt. Das bedeutet praktisch, dass Funktionen
      der entsprechenden APIs andere Funktionen als Parameter erwarten.
      Die übergebene Funktion wird dann nach dem Eintreten eines
      bestimmten Ereignisses aufgerufen. Die Funktion behält dabei ihren
      ursprünglichen Kontext, kann also auf Objekte zugreifen, die in
      der Umgebung (genauer: im \emph {Namespace}) des Aufrufers gar
      nicht bekannt sind (sog.  \emph {Closure}).

      Erwähnenswert sind außerdem Dateiobjekte. Sie werden meist durch
      Aufruf der eingebauten Funktion \lstinline $open$ mit dem
      Dateinamen als Parameter erzeugt. Was diesen Typ so bedeutend
      macht, sind die zahlreichen \emph {file-like objects} in Python.
      Sie sind ein gutes Beispiel dafür, wie in Python lose Verträge
      über das Verhalten eines Objekts geschlossen werden. Anstatt genau
      vorzuschreiben, dass ein zu behandelndes Objekt vom Typ \lstinline
      $file$ sein muss, verlangen Funktionen oder Methoden ein file-like
      object als Parameter. Es soll also Methoden wie \lstinline $read$,
      \lstinline $write$, \lstinline $flush$ und \lstinline $close$
      implementieren.\footnote {\cite[Kapitel~2.3.9]{pylib}} Dass nicht
      nur Klassen für einfache Textdateien solche Methoden sinnvoll
      bereitstellen können, kann man sich schnell denken. So gibt es
      file-like objects für komprimierte und XML-Dateien,
      Netzwerksockets, einfache Zeichenketten und einiges mehr. Der
      Benutzer dieser Objekte muss aber gar nicht wissen, womit er es
      genau zu tun hat, so lange er alle erwarteten Methoden vorfindet.
      Das kann auch nur eine Teilmenge aller Methoden des Typs
      \lstinline $file$ sein. Es gibt allerdings keine Möglichkeit
      anzuzeigen, dass Objekte eines bestimmten Typs ein bestimmtes
      Interface (man spricht in diesem Zusammenhang auch häufig von
      \emph {Protokollen}) bereitstellt. Eventuell wird dieses Problem
      in Python 3.0 angegangen.\footnote {Siehe \citep {adaption} für
      ein diesbezügliches Gedankenspiel.}

