web-dev-qa-db-de.com

Wie ist die Variable __name__ in einem Python-Modul definiert?

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.

23
Jeremy Banks

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.

22
Martijn Pieters

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)
2
User