Mir ist das Standardbeispiel bekannt: Wenn Sie ein Modul direkt ausführen, ist die globale Variable __name__
als "__main__"
definiert. Nirgendwo in der Dokumentation kann ich jedoch genau beschreiben, wie __name__
im allgemeinen Fall definiert ist. Die Moduldokumentation sagt ...
Innerhalb eines Moduls steht der Name des Moduls (als String) als Wert der globalen Variablen
__name__
zur Verfügung.
... aber was bedeutet "der Name des Moduls"? Ist es nur der Name des Moduls (der Dateiname ohne .py
) oder enthält es auch den vollqualifizierten Paketnamen?
Wie wird der Wert der Variablen __name__
in einem Python-Modul ermittelt? Geben Sie für Bonuspunkte genau an, wo diese Operation im Python-Quellcode ausgeführt wird.
Es wird auf den absoluten Namen des Moduls beim Importieren gesetzt. Wenn Sie es als foo.bar
importiert haben, wird __name__
auf 'foo.bar'
gesetzt.
Der Name wird im Modul import.c
festgelegt. Da dieses Modul jedoch verschiedene Importtypen (einschließlich Zip-Importe, Nur-Bytecode-Importe und Erweiterungsmodule) verarbeitet, gibt es mehrere Codepfade, durch die nachverfolgt werden kann .
Normalerweise werden import
-Anweisungen in einen Aufruf von __import__
übersetzt, der standardmäßig als Aufruf von PyImport_ImportModuleLevelObject
implementiert ist. In der __import__()
Dokumentation erfahren Sie, was die Argumente bedeuten. Innerhalb von PyImport_ImportModuleLevelObject
werden relative Namen aufgelöst, sodass Sie die Variablen name
dort nachlaufen können, wenn Sie möchten.
Der Rest des Moduls übernimmt die eigentlichen Importe, wobei PyImport_AddModuleObject
das eigentliche Namespace-Objekt erstellt und den name
-Schlüssel setzt. Sie können den name
-Wert jedoch auf PyImport_ImportModuleLevelObject
zurückverfolgen. Beim Erstellen eines Modulobjekts wird der __name__
-Wert im moduleobject.c
-Objektkonstruktor festgelegt.
Die Variable __name__
ist ein Attribut des Moduls, auf das der Name zugreifen kann.
import os
assert os.__== 'os'
Beispiel eines selbst erstellten Moduls, das den Importmechanismus abruft:
>>> import types
>>> m = types.ModuleType("name of module") # create new module with name
>>> exec "source_of_module = __name__" in m.__dict__ # execute source in module
>>> m.source_of_module
'name of module'
Zeilen vom Typenmodul:
import sys
ModuleType = type(sys)