Подтвердить что ты не робот

Как определена переменная __name__ в модуле Python?

Я знаю стандартный пример: если вы выполняете модуль напрямую, то глобальная переменная __name__ определяется как "__main__". Однако нигде в документации я не могу найти точное описание того, как __name__ определяется в общем случае. Документация модуля говорит...

Внутри модуля имя модуля (как строка) доступно как значение глобальной переменной __name__.

... но что это означает под названием "имя модуля"? Это просто имя модуля (имя файла с .py удалено), или оно включает также полное имя пакета?

Как определяется значение переменной __name__ в модуле Python? Для бонусных точек укажите, где именно в исходном коде Python выполняется эта операция.

4b9b3361

Ответ 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)