"Was ist ein Namensraum?", höre ich dich fragen. Gut, das ist irgendwie schwierig zu erklären. Nicht weil das besonders kompliziert ist, aber weil jede Sprache sich hierzu anders verhält. Das Konzept ist einfach: Ein Namensraum ist ein Raum oder ein Gebiet innerhalb eines Programms, wo ein Name (Variable, Klasse usw.) gültig ist.
Man ist dazu gekommen, weil die frühen Programmiersprachen (wie BASIC) nur globale Variablen hatten; das sind solche, die innerhalb des gesamten Programmes sichtbar waren - sogar innerhalb von Funktionen. Dies machte die Wartung von großen Programmen schwierig, da man hierbei leicht einen Teil des Programmes ändern konnte, ohne dass andere Programmteile dies bemerkten - dies wurde auch Nebeneffekt genannt. Um dies zu umgehen, führten spätere Sprachen (einschließlich der modernen BASICs) das Konzept der Namensräume ein. (Bei C++ hat dies zum Extrem geführt, dass es dem Programmierer erlaubt, beliebige Namensräume irgendwo in einem Programm zu erzeugen. Dies ist nützlich für die Erzeuger von Bibliotheken, die gerne möchten, dass ihre Funktionsnamen einzigartig bleiben sollen, wenn sie mit Bibliotheken anderer Lieferanten vermischt werden.)
In Python erzeugt jedes Modul seinen eigenen Namensraum. Um auf diese Namen zugreifen zu können, müssen wir sie entweder mit vorangestelltem Modulnamen verwenden oder explizit diejenigen Namen importieren, die wir innerhalb des Namensraumes unseres eigenen Moduls verwenden wollen. Das ist aber nichts Neues, wir haben dies bereits schon mit den sys - und string - Modulen getan. In einem gewissen Sinne erzeugt auch eine Klassendefinition ihren eigenen Namensraum. Um dann Zugriff auf eine Methode oder Eigenschaft einer Klasse zu erhalten, müssen wir den namen der Instanz - Variablen oder den Klassennamen zuerst verwenden.
In Python gibt es lediglich 3 Namensräume (oder Geltungsbereiche):
So weit so gut. Wie passt dies aber zusammen, wenn Variablen in unterschiedlichen Namensräumen den selben Namen haben? Oder wenn ein Name nicht im momentanen Namensraum referenziert ist? Schauen wir zuerst einmal auf die vorherige Situation: Wenn eine Funktion auf eine Variable, genannt X, zugreift und es es existiert ein X dort in dieser Funktion (lokaler geltungsbereich), dann ist dies die einzige die von Python gesehen und verwendet wird. Es ist der Job des Programmierers, Namenskonflikte zu vermeiden, so dass eine lokale Variable und eine Modulvariable nicht zusammen in einer Funktion erforderlich sind - die lokale Variable wird die globale überdecken.
Grundsätzlich sollte man die Verwendung von 'globalen' Anweisungen minimieren; es ist gewöhnlich besser, die Variable als Parameter durchzugeben und dann die modifizierte Variable zurückzugeben.
Der zweite Punkt, wo auf einen Namen Bezug genommen wird, welcher sich nicht im aktuellen lokalen Namensraum befindet, wird folgendermaßen aufgelöst: Die Funktion wird innerhalb des lokalen Namensraumes nachschauen, wenn sie ihn dort nicht findet, wird sie im modularen Geltungbereich nachschauen, und wenn er auch da nicht auftaucht, im eingebauten Geltungsbereiches. Der einzige Haken daran taucht auf, wenn wir einen Wert einer externen Variablen zuweisen möchten. Normalerweise würden wir einen neuen Variablennamen erzeugen, da wir aber nicht möchten, dass dies geschieht, so müssen wir ihn noch einmal als global spezifizieren, um sicher zu gehen, dass wir keine lokale Version des Namens erzeugen.
Wir können dies alles im folgenden Beispiel (welches nur zu reinen Erläuterungszwecken dient!) bei der Arbeit sehen:
# Variablen mit modularem Geltungsbereich W = 5 Y = 3 #Parameter sind wie Funktionsvariablen, #somit hat X lokalen Geltungsbereich def spam(X): #sage der Funktion, sie soll auf der Modulebene nachschauen und kein eigenes W erzeugen global W Z = X*2 # neue variable Z mit lokalem Geltungsbereich erzeugt W = X+5 # verwende Module W wie oben angewiesen if Z > W: # drucke als einen 'eingebauten Geltungsbereichs-' Name print "2 x X ist größer als X + 5" return Z else: return Y # kein lokales Y , also Module-Version, wird verwendet
Wenn wir jetzt ein Modul wie sys importieren, machen wir den Namen sys lokal zugänglich und dann können wir auf Namen innerhalb des sys-Modul-Namensraumes durch die eben gezeigte Namensqualifizierung zugreifen. Wenn wir eingeben:
from sys import exit
bringen wir nur die exit - Funktion in den lokalen Namensraum. Wir können keine anderen sys - Namen verwenden, nicht einmal sys selbst.
BASIC verwendet eine zu Python gegensätzliche Behandlungsweise, indem es alle Variablen grundsätzlich GLOBAL macht (aus Kompatibilitätsgründen zu alten BASIC-Programmen), es erlaubt dem Programmierer aber auch die Erzeugung von LOKALEN Variablen innerhalb von Funktionen.
So weit ich sagen kann, gibt es in Tcl keine Namensraumkontrolle. Möglicherweise aufgrund der außergewöhnlichen Art, wie Tcl das Programm grammatikalisch zergliedert. Auf jeden Fall scheint es so, dass alle Variablen in ihrer unmittelbaren Umgebung lokal gültig sind - Variablen auf Dateiebene sind nur sichtbar für Befehle innerhalb der Datei und Prozedur-Variablen sind nur sichtbar innerhalb der Prozedur. Um zwischen zwei Namensräumen zu kommunizieren, musst du die Werte als Parameter übergeben.
Im falle von Fragen oder hinweisen sende bitte eine E-Mail auf
Englisch an alan.gauld@yahoo.co.uk
oder auf Deutsch an bup.schaefer@freenet.de