10. Lokale und Globale Variablen

Damit die Schnittstellen einer Funktion überschaubar bleiben, beeinflusst die Manipulation einer Variable innerhalb einer Funktion den Rest des Programms normalerweise nicht.

In Python ist das dadurch realisiert, dass jede Funktion einen eigenen Namespace hat, der beim Aufruf neu erzeugt wird und verschwindet, wenn sie fertig ist. Dieser Namespace heißt lokal.

Der Namespace, in dem man außerhalb einer Funktion ist, heißt globaler Namespace. Er spielt eine besondere Rolle, weil in ihm nachgesehen wird, wenn die Suche im lokalen Namespace erfolglos war.

Wenn wir 5 eingegeben haben, sieht es in der Funktion incString folgendermaßen aus:

Macht euch klar, was passiert, wenn wir in incString die Funktion int aufrufen – ein Funktionsaufruf ist ja nichts anderes als die Aufforderung an Python, nach dem an den Namen gebundenen Wert zu suchen und diesem Wert (sinngemäß) zu sagen: Hör zu, hier hast du ein paar Argumente, verarbeite sie doch bitte mal.

Im lokalen Namespace von incString stehen zu diesem Zeitpunkt nur s und i, die Suche nach int muss also scheitern. Danach sucht Python im globalen Namespace und wird dort fündig. Wäre schon ein int im lokalen Namespace gewesen, wäre das aufgerufen worden.

Zuweisungen landen immer im lokalen Namespace. Wenn man etwa an den Anfang von incString ein s = "7" geschrieben hätte, wäre die Situation danach so:

Beachtet: s ist im globalen Namespace immer noch an "5" gebunden. Sobald die Funktion vorbei ist, erinnert nichts Python daran, dass es mal ein s gab, das an s = "7" gebunden war.

Es ist in Ordnung, Funktionen und ähnliches aus dem globalen Namespace zu holen.

Es ist gefährlich und böse, Variablen aus dem globalen Namespace zu holen (“globale Variablen”). Hauptgrund dafür ist, dass auf diese Weise die Schnittstelle der Funktion nicht mehr nur durch ihre Argumente und ihren Rückgabewert definiert ist, sondern auch noch durch den Wert der verwendeten globalen Variablen. Das entwertet die Lokalität der Funktion erheblich.

Im Prinzip würde das ähnlich natürlich auch für Funktionen gelten – aber die Schnittstelle einer Funktion ändert sich im Allgemeinen über einen Programmlauf hinweg nicht, so dass Funktionen als Konstanten aufgefasst werden können. Konstanten aber gehören nicht zur Schnittstelle einer Funktion. Da sich eine Konstante nämlich per definitionem nicht ändern kann, kann sie auch das Verhalten der Funktion nicht beeinflussen.

Deshalb: Alle Daten, die eine Funktion braucht, müssen aus den Argumenten kommen.

Übungen zu diesem Abschnitt

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

(1)

K. R. Acher hat sein incString so geschrieben:

def incString(str):
  i = int(str)
  i = i+1
  return str(i)

Er ist ein wenig überrascht, als sein Python folgendes tut:

>>> incString("7")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in incString
TypeError: 'str' object is not callable

Was ist passiert?


Markus Demleitner

Copyright Notice