Python Namensräume (Namespace)             (C) 2017-2022 T.Birnthaler OSTC GmbH
==============================

--> python-scope.txt        Scope/Sichtbarkeitsbereich
--> python-namespace.txt    Namespace/Namensraum
--> python-lifetime.txt     Lebensdauer/Lifetime/Existenz/Gültigkeitsbereich

Der Begriff "Namespace/Namensraum" bezieht sich auf die Bereiche in Python, in
denen Namen EINDEUTIG sind. In getrennten Namensräumen kann der gleiche Name
parallel verwendet werden, ohne dass es zu Überschneidungen kommt. Namensräume
sind GLOBAL, d.h. wenn ein Namensraum ansprechbar ist, dann sind auch alle
Namen darin ansprechbar durch die Notation NAMESPACE.NAME.

Folgende Namensräume (namespaces) gibt es in Python:

+------------+----------------------------------------------------------------+
| Namensraum | Bedeutung                                                      |
+------------+----------------------------------------------------------------+
| Built-in   | In Python-Interpreter direkt eingebaut (z.B. len, sum, ...)    |
|            | Zugriff per NAME oder builtins.NAME (nach "import builtins")   |
| Global     | Im Skript (Hauptmodul) außerhalb von Funktion, Klasse, Objekt  |
|            | Zugriff per NAME oder __main__.NAME (nach "import __main__")   |
+------------+----------------------------------------------------------------+
| Modul      | Zugriff per MODUL.NAME nach "import MODUL"                     |
| Funktion   | Zugriff per FUNKTION.NAME nach "def FUNKTION(...): ..."        |
| Klasse     | Zugriff per KLASSE.NAME nach "class KLASSE: ..." oder Datentyp |
| Objekt     | Zugriff per OBJEKT.NAME nach OBJEKT = WERT                     |
+------------+----------------------------------------------------------------+

Zugriff auf die in Python direkt eingebauten ("built-in") Namen ist über das
Modul (den Namensraum) "builtins" grundsätzlich immer möglich:

  import builtins               # Namensraum "builtins" importieren
  erg = builtins.len("hallo")   # Statt len("hallo")

Zugriff auf die im Skript (Hauptmodul) vorhandenen Namen ist über das Modul
(den Namensraum) "__main__" grundsätzlich immer möglich:

  name = "skript"        # Name im Namensraum des Skriptes
  import __main__        # Namensraum des Skriptes importieren
  print(__main__.name)   # Statt print(name)

Im folgenden Beispiel wird der gleiche Name "len" in unterschiedlichen
Namensräumen parallel verwendet und referenziert jeweils verschiedene Werte:

  import builtins
  import __main__
  len = "modul/global"
  def f(): pass
  f.len = "funktion"
  class C(): pass
  C.len = "klasse"
  o = C()
  o.len = "objekt"

  for name in (builtins.len, __main__.len, len, f.len, C.len o.len):
      print("NAME", name, type(name))