Routineaufgaben mit Python automatisieren. Al Sweigart
Чтение книги онлайн.

Читать онлайн книгу Routineaufgaben mit Python automatisieren - Al Sweigart страница 41

Название: Routineaufgaben mit Python automatisieren

Автор: Al Sweigart

Издательство: Bookwire

Жанр: Математика

Серия:

isbn: 9783960889571

isbn:

СКАЧАТЬ

      print('c() starts') image

      print('c() returns')

      def d():

      print('d() starts')

      print('d() returns')

      a() image

      Wenn Sie dieses Programm ausführen, erhalten Sie die folgende Ausgabe:

      a() starts

      b() starts

      c() starts

      c() returns

      b() returns

      d() starts

      d() returns

      a() returns

      Die Ausführung dieses Programms können Sie sich auf https://autbor.com/abcdcallstack/ ansehen. Wird die Funktion a() aufgerufen (image), so ruft sie ihrerseits b() auf (image), die wiederum c() aufruft (image). Die Funktion c() ruft nichts auf, sondern gibt lediglich die Zeilen c() starts (image) und c() returns aus, bevor die Steuerung zu der Zeile in b() zurückspringt, in der c() aufgerufen wurde (image). Dort angekommen, springt die Steuerung zu der Zeile in a() zurück, in der b() aufgerufen wurde (image). Die Ausführung geht jetzt mit der nächsten Zeile in a() weiter, nämlich mit dem Aufruf von d() (image). Ebenso wie c() ruft auch d() nichts auf, sondern gibt lediglich d() starts und d() returns aus, bevor sie die Steuerung an die Zeile in a() zurückgibt, in der sie aufgerufen wurde. Die letzte Zeile in a()gibt a() returns aus und springt dann zu dem ursprünglichen Aufruf von a() am Ende des Programms zurück (image).

      Mithilfe des Aufrufstacks merkt sich Python, wohin die Steuerung nach einem Funktionsaufruf jeweils zurückspringen muss. Dieser Stack wird jedoch nicht in einer Variablen gespeichert, sondern hinter den Kulissen von Python gehandhabt. Wenn das Programm eine Funktion aufruft, erstellt Python ein Frameobjekt an der Spitze des Aufrufstacks. In Frameobjekten ist die Zeilennummer des ursprünglichen Funktionsaufrufs gespeichert, sodass sich Python merken kann, wohin es zurückspringen muss. Erfolgt ein weiterer Funktionsaufruf, legt Python im Stack ein weiteres Frameobjekt auf das vorhergehende.

      Beim Rücksprung aus einer aufgerufenen Funktion entfernt Python das zugehörige Frameobjekt vom Stapel und fährt mit der Ausführung in der Zeile mit der gespeicherten Nummer fort. Frameobjekte werden dabei immer oben auf den Stapel gelegt und auch dort wieder von ihm heruntergenommen, niemals an einer anderen Stelle. Abb. 3–2 zeigt die verschiedenen Zustände des Aufrufstacks von abcdCallStack.py, während die einzelnen Funktionen aufgerufen werden und zurückspringen.

       Abb. 3–2 Frameobjekte im Aufrufstack im Verlauf der Funktionsaufrufe und Rücksprünge in abcdCallStack.py

      Das oberste Objekt auf dem Stack besagt, welche Funktion gerade ausgeführt wird. Wenn der Aufrufstack leer ist, erfolgt die Ausführung außerhalb von Funktionen.

      Beim Aufrufstack handelt es sich um eine technische Hintergrundeinrichtung, die Sie nicht unbedingt kennen müssen, um Programme schreiben zu können. Es reicht zu wissen, dass Funktionsaufrufe zu der Zeile zurückkehren, von der aus sie aufgerufen wurden. Allerdings erleichtern Kenntnisse des Aufrufstacks das Verständnis der lokalen und globalen Gültigkeitsbereiche, die wir uns im folgenden Abschnitt ansehen.

       Lokaler und globaler Gültigkeitsbereich

      Parameter und Variablen, die innerhalb einer aufgerufenen Funktion zugewiesen werden, befinden sich im lokalen Gültigkeitsbereich der Funktion. Dagegen haben Variablen, die außerhalb von Funktionen zugewiesen werden, einen globalen Gültigkeitsbereich. Variablen in einem lokalen Gültigkeitsbereich werden als lokale Variablen bezeichnet, Variablen im globalen Gültigkeitsbereich als globale Variablen. Eine Variable ist entweder lokal oder global, aber niemals beides.

      Den Gültigkeitsbereich können Sie sich wie einen Behälter für Variablen vorstellen. Wird ein Gültigkeitsbereich zerstört, so gehen alle Werte der darin enthaltenen Variablen verloren. Es gibt nur einen globalen Gültigkeitsbereich. Er wird erstellt, wenn das Programm beginnt, und am Ende des Programms zerstört. Damit sind alle seine Variablen vergessen. Wäre das nicht der Fall, so würden beim nächsten Start des Programms alle Variablen immer noch die Werte aufweisen, die sie bei der letzten Ausführung hatten.

      Ein lokaler Gültigkeitsbereich entsteht beim Aufruf einer Funktion. Jegliche Variablen, die in dieser Funktion zugewiesen werden, befinden sich in diesem lokalen Gültigkeitsbereich. Wenn die Funktion die Steuerung zurückgibt, wird der lokale Gültigkeitsbereich zerstört, sodass seine Variablen verloren gehen. Beim nächsten Aufruf der Funktion sind die Werte, die beim letzten Aufruf in den lokalen Variablen gespeichert waren, nicht mehr vorhanden. Die lokalen Variablen werden auch in Frameobjekten auf dem Aufrufstack abgelegt.

      Das Prinzip der Gültigkeitsbereiche hat einige wichtige Auswirkungen:

       Code im globalen Gültigkeitsbereich, also außerhalb von Funktionen, kann keine lokalen Variablen nutzen.

       Code im lokalen Gültigkeitsbereich kann dagegen auf globale Variablen zugreifen.

       Code im lokalen Gültigkeitsbereich einer Funktion kann keine Variablen aus anderen lokalen Gültigkeitsbereichen nutzen.

       Sie können für zwei Variablen den gleichen Namen wählen, sofern sie sich in unterschiedlichen Gültigkeitsbereichen befinden. Es kann also beispielsweise sowohl eine lokale als auch eine globale Variable namens spam geben.

      Warum gibt es in Python verschiedene Gültigkeitsbereiche, anstatt alle Variablen global zu machen? Wenn eine Variable durch den Code in einem bestimmten Funktionsaufruf bearbeitet wird, dann interagiert die Funktion mit dem Rest des Programms nur durch ihre Parameter und den Rückgabewert. Bei einem Fehler schränkt das die Menge der Codezeilen ein, die dafür verantwortlich sein können. Wenn in einem Programm, das ausschließlich globale Variablen enthält, ein Fehler dafür sorgt, dass einer Variablen ein falscher Wert zugewiesen wird, ist es ziemlich schwer, die entsprechende Stelle zu finden. Dieser Wert könnte überall in dem Programm zugewiesen worden sein – und das kann irgendwo in Hunderten oder gar Tausenden von СКАЧАТЬ