Lokale und globale Namespaces
#!/usr/bin/env python
# Namespaces
# In Funktionen gibt es lokale Namensraeume,
# soll ein Objekt global uebernommen werden, muss dies
# mittels global geschehen.
# - Objekte aus dem Hauptprogramm bleiben auch in
# Unterfunktionen lesend global, beim Schreibzugriff
# werden sie aber lokal, es sei denn, es wird explizit
# "global " angegeben.
# - (Streng genommen wird beim Schreibzugriff auf ein
# Objekt aus dem globalen Namespace ein zweites Objekt
# mit gleichem Namen im lokalen Namespace erzeugt,
# welches das Objekt aus dem globalen Namespace
# ueberdeckt.
def test():
print "Funktionseinstieg"
print locals()
print globals()
print "Globalisierung..."
a = "Ciao"
global b
b = "Erde"
c = "Universum"
print "Gaendert: a=",a,", b=",b,", c=",c
print locals()
print globals()
print "Programmstart"
print locals()
print globals()
a = "Hallo"
b = "Welt"
print "Variablendefinition"
print "Objekte am Programmanfang: a=",a,", b=",b
print locals()
print globals()
test()
print "Objekte am Programmende : a=",a,", b=",b
print locals()
print globals()
Das Script verwendet das erste Mal eine selbstgeschriebene Funktion, die durch def angelegt wird. Ihr Name ist test, und die leere Klammer bedeutet, dass sie erstmal keine Variablen oder Variablenwerte aus den aufrufenden Funktionen übernimmt.Interessant sind die Befehle locals() und globals(), die jeweils den Inhalt des lokalen und globalen Namespace ausgeben, wobei natürlich festzustellen ist, dass es einen globalen Namespace nur innerhalb von Funktionen geben kann, weil das Hauptprogramm nur über einen Namensraum verfügt.
Führt man das Programm aus, gibt es folgendes aus:
Programmstart
{'__builtins__': , '__name__': '__main__', '__file__': './02_namespaces.py', 'test': , '__doc__': None}
{'__builtins__': , '__name__': '__main__', '__file__': './02_namespaces.py', 'test': , '__doc__': None}
Variablendefinition
Objekte am Programmanfang: a= Hallo , b= Welt
{'a': 'Hallo', 'b': 'Welt', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
{'a': 'Hallo', 'b': 'Welt', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
Funktionseinstieg
{}
{'a': 'Hallo', 'b': 'Welt', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
Globalisierung...
Gaendert: a= Ciao , b= Erde , c= Universum
{'a': 'Ciao', 'c': 'Universum'}
{'a': 'Hallo', 'b': 'Erde', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
Objekte am Programmende : a= Hallo , b= Erde
{'a': 'Hallo', 'b': 'Erde', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
{'a': 'Hallo', 'b': 'Erde', '__builtins__': , '__file__': './02_namespaces.py', 'test': , '__name__': '__main__', '__doc__': None}
Die ersten beiden Zeilen zeigen, wie der Namespace aussieht, wenn noch nicht viel passiert ist: Es gibt ein paar eingebaute Module, das File, das das Programm enthält, heißt 02_namespace.py, und es gibt eine definierte Funktion test.
Interessant wird es das erste Mal nach der Deklaration der Variablen a und b, die nun in den globalen Namespace einfliessen (der an der Stelle wiederrum identisch ist mit dem lokalen).
Richtig spannend wird es dann nach dem Funktionsaufruf: Hier ist der lokale Namespace plötzlich leer, wie die der erste Satz geschweifter Klammern anzeigt, währen der globale sich nicht verändert hat.
Dann geschieht zweierlei: Durch die Anweisung global b wird die Variable b von der Funktion test() aus beschreibbar, außerdem wird die Variable a neu deklariert, und c kommt hinzu.
Nach der Globalisierung sieht der lokale Namespace schon anders aus, er enthält a und c, aber immer noch nicht b. Dafür ist im globalen Namespace ersichtlich, dass die Änderung b='Erde' ihre Wirkung nicht verfehlt hat. Wenn sich die Funktion beendet, ist b immer noch 'Erde', aber nicht 'Welt', wie es noch am Anfang der Fall war.
Das c als neue Variable im lokalen Namespace ist, ist nicht verwunderlich, man sieht aber auch sehr schön, dass die lokale Variable a, deren Wert nun 'Ciao' ist, das global deklarierte a überlagert. In der Funktion test hat man nun keinen Zugriff mehr auf die globale Variable a.
cptsalek - 16. Mai, 14:01
Trackback URL:
https://cptsalek.twoday.net/stories/2015199/modTrackback