Как определена переменная __name__ в модуле Python?
Я знаю стандартный пример: если вы выполняете модуль напрямую, то глобальная переменная __name__
определяется как "__main__"
. Однако нигде в документации я не могу найти точное описание того, как __name__
определяется в общем случае. Документация модуля говорит...
Внутри модуля имя модуля (как строка) доступно как значение глобальной переменной __name__
.
... но что это означает под названием "имя модуля"? Это просто имя модуля (имя файла с .py
удалено), или оно включает также полное имя пакета?
Как определяется значение переменной __name__
в модуле Python? Для бонусных точек укажите, где именно в исходном коде Python выполняется эта операция.
Ответы
Ответ 1
Устанавливается абсолютное имя модуля как импортированное. Если вы импортировали его как foo.bar
, тогда __name__
устанавливается на 'foo.bar'
.
Имя определяется в модуле import.c
, но поскольку этот модуль обрабатывает различные типы импорта (включая импорт zip, импорт и расширение только для байт-кода ) существует несколько путей кода для прослеживания.
Обычно операторы import
переводятся на вызов __import__
, который по умолчанию реализован как вызов PyImport_ImportModuleLevelObject
. См. Документацию __import__()
, чтобы понять, что означают аргументы. В пределах PyImport_ImportModuleLevelObject
относительные имена разрешены, поэтому вы можете преследовать переменные name
там, где хотите.
Остальная часть модуля обрабатывает фактический импорт, при этом PyImport_AddModuleObject
создает фактический объект пространства имен и устанавливает ключ name
, но вы можете отследить это значение name
до PyImport_ImportModuleLevelObject
. Создавая объект модуля, значение __name__
устанавливается в конструкторе объектов moduleobject.c
.
Ответ 2
Переменная __name__
- это атрибут модуля, доступный по имени.
import os
assert os.__name__ == 'os'
Пример самостоятельно созданного модуля, который отображает механизм импорта:
>>> 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'
Линии из типов:
import sys
ModuleType = type(sys)