Вы можете использовать тот факт, что модуль доступен как sys.modules['__main__']
:
"""
Is this what you want?
"""
import sys
if __name__ == '__main__':
help(sys.modules['__main__'])
вывод
Help on module __main__:
NAME
__main__ - Is this what you want?
DATA
__annotations__ = {}
FILE
/Users/akx/Desktop/so61453557.py
(END)
Или для файла, который не имеет строки документации, но имеет комментарии :
# This is
# the description
# and not even a haiku
import sys
if __name__ == '__main__':
help(sys.modules['__main__'])
Help on module __main__:
NAME
__main__
DESCRIPTION
# This is
# the description
# and not even a haiku
DATA
__annotations__ = {}
FILE
/Users/akx/Desktop/so61453557.py
(END)
РЕДАКТИРОВАТЬ
Хорошо, это оказалось более интересным, чем я думал, и углубиться в CPython внутренности!
python -i so61453557.py
и python -m so61453557
действуют здесь по-разному.
Первые вызывают pymain_run_file()
, что вызывает PyRun_AnyFileExFlags()
, что вызывает PyRun_SimpleFileExFlags()
. Насколько я могу судить, он в основном синтезирует модуль __main__
и оценивает файл в этом контексте, используя PyRun_FileExFlags
.
Последний вызывает pymain_run_module()
, чей реальный лог c содержится в модуле stdlib runpy.py
(_run_module_as_main
).
После этого
Когда -i
установлено (interactive
, inspect
), вызывается pymain_repl()
, который может вызвать интерактивный хук, если установлен (например, завершение чтения строки и прочее), а затем вызывает PyRun_AnyFileFlags(stdin, "<stdin>", cf)
.
Я не знаю, что очищает __main__
после запуска файла (это может быть XDECREF()
в конце PyRun_SimpleFileExFlags
), но вот некоторые выводы.
python -i -m so61453557
, кажется, сохраняет __main__
(<module '__main__' from 'so61453557.py'>
), поэтому вы можете запустить help(sys.modules['__main__'])
, как вы ожидаете в REPL. python -i so61453557.py
: при входе в REPL модуль __main__
возвращается в <module '__main__' (<_frozen_importlib_external.SourceFileLoader object at 0x10fb2e990>)>
. python
имеет третью версию __main__
: <module '__main__' (built-in)>
.
Как хак, я думал, что можно sys.modules['hack'] = sys.modules['__main__']
, но это не так не работает; Сам модуль изменяется, и объекты модуля не могут быть выбраны, поэтому вы также не можете назначить copy.copy(main)
.
Но, TL; DR: Это работает, если вы используете python -i -m something
, это не так, если вы делаете python -i something.py
.