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

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

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

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

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


person Jeremy    schedule 08.04.2013    source источник
comment
Я видел варианты этого вопроса, но я рад, что кто-то углубил тему.   -  person Nathan Basanese    schedule 14.04.2015


Ответы (2)


Он устанавливается на абсолютное имя модуля как импортированного. Если вы импортировали его как 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 конструкторе объекта. .

person Martijn Pieters    schedule 08.04.2013
comment
Кроме того, подпункт as в import не меняет атрибут __name__. - person andy; 26.01.2015

Переменная __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)
person User    schedule 08.04.2013
comment
Обратите внимание, что в Python 3 exec — это функция: exec("source_of_module = __name__", m.__dict__) - person Mihai Capotă; 13.07.2016