Historie der Frage
Namespaces (Namensräume) sind eines der grundlegenden Konzepte in Python, das seit den ersten Implementierungen der Sprache vorhanden ist. Sie dienen der Systematisierung von Namen, um Konflikte zwischen Variablen, Funktionen und Klassen aus verschiedenen Teilen des Programms zu vermeiden.
Problem
In großen Projekten gibt es viele Funktionen, Klassen, Variablen und Module. Ohne korrekte Verwendung von Namespaces besteht die Möglichkeit, wichtige Namen zu überschreiben, unerwartete Schatten von Variablen zu erhalten und Schwierigkeiten beim Testen und Erweitern zu haben.
Lösung
In Python ist ein Namespace eine Zuordnung (mapping), die Namen mit Objekten verknüpft. Es gibt verschiedene Ebenen von Namensräumen: lokal, global, Modulräume, Klassen. Das Verständnis dieser Aufteilung gewährleistet den richtigen Zugriff auf die benötigten Objekte und minimiert Konflikte.
Codebeispiel:
def foo(): x = 10 # x im lokalen Namensraum der Funktion print(x) y = 20 # y im globalen Namensraum des Moduls foo() print(y)
Wichtige Merkmale:
Was passiert, wenn in derselben Funktion eine lokale Variable mit demselben Namen wie eine globale deklariert wird?
Die lokale "überschattet" die globale während der Ausführung der Funktion; außerhalb der Funktion bleibt die globale unverändert.
a = 1 def test(): a = 2 print(a) # 2 test() print(a) # 1
Wie erhält man eine Liste aller Namen im aktuellen Namensraum?
Die Funktionen locals(), globals(), dir() geben die entsprechenden Zuordnungen oder Listen von Namen im aktuellen Gültigkeitsbereich/Namensraum zurück.
Was unterscheidet die Namensräume von Klassen und Instanzen?
Der Klassen-Namespace definiert Attribute, die allen Instanzen der Klasse gemeinsam sind. Der Instanz-Namespace sind Attribute eines bestimmten Objekts. Änderungen in der Instanz beeinflussen nicht die Klasse und umgekehrt.
Verwendeten from mymodule import * in allen Teilen eines großen Projekts. Schließlich wurden die Namen von Funktionen überschrieben, wodurch schwer auffindbare Bugs aufgrund von Namenskonflikten zwischen Paketen entstanden.
Vorteile:
Nachteile:
Wechselten zu Import-Aliasen (import mymodule as mm), klare Strukturierung der Module.
Vorteile:
Nachteile: