Je connais l'exemple standard : si vous exécutez un module directement, sa variable globale __name__
est définie comme étant "__main__"
. Cependant, je ne trouve nulle part dans la documentation une description précise de la manière dont __name__
est défini dans le cas général. La documentation de module indique ...
Dans un module, le nom du module (sous forme de chaîne) est disponible en tant que valeur de la variable globale
__name__
.
... mais qu'est-ce que cela signifie par "le nom du module"? S'agit-il uniquement du nom du module (le nom du fichier avec .py
supprimé) ou comprend-il également le nom du package qualifié complet?
Comment la valeur de la variable __name__
dans un module Python est-elle déterminée? Pour les points bonus, indiquez précisément où, dans le code source Python, cette opération est effectuée.
Il est défini sur le nom absolu du module tel qu'importé. Si vous l'avez importé en tant que foo.bar
, alors __name__
est défini sur 'foo.bar'
.
Le nom est déterminé dans le module import.c
, mais étant donné que ce module gère différents types d'importations (y compris les importations Zip, les importations en bytecode uniquement et les modules d'extension), il existe plusieurs chemins de code à suivre.
Normalement, les instructions import
sont traduites en un appel à __import__
, qui est par défaut implémenté en tant qu'appel à PyImport_ImportModuleLevelObject
. Consultez la documentation __import__()
pour avoir une idée de la signification des arguments. Dans PyImport_ImportModuleLevelObject
, les noms relatifs sont résolus, vous pouvez donc y rechercher les variables name
si vous le souhaitez.
Le reste du module gère les importations réelles, avec PyImport_AddModuleObject
créant l'objet d'espace de nom réel et définissant la clé name
, mais vous pouvez suivre cette valeur name
jusqu'à PyImport_ImportModuleLevelObject
. En créant un objet module, sa valeur __name__
est définie dans le constructeur d'objet moduleobject.c
.
La variable __name__
est un attribut du module qui serait accessible par son nom.
import os
assert os.__== 'os'
Exemple de module auto-créé qui analyse le mécanisme d'importation:
>>> 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'
Lignes du module types:
import sys
ModuleType = type(sys)