Как импортировать модуль как __main__?

У меня есть модуль, который имеет обычный

if __name__ == '__main__':
    do stuff...

идиомы.

Я хотел бы импортировать это из другого модуля и обмануть его в запуск этого кода. Есть ли способ сделать это?

Я должен упомянуть, по причинам, в которых я не буду входить, я не могу изменить код в импортированном модуле. Мне нужно каким-то образом изменить процедуру импорта, чтобы имя было основным при импорте, возможно, с использованием ihooks или аналогичного.

Ответ 1

Существует, выполните script вместо импорта. Но я считаю это крайне хакерским решением.

Однако идеальный шаблон был бы следующим:

def do_stuff():
    ... stuff happens ...

if __name__ == '__main__':
    do_stuff()

что вы можете сделать:

from mymodule import do_stuff
do_stuff()

РЕДАКТИРОВАТЬ: ответ после разъяснения о невозможности редактировать код модуля.

Я бы никогда не рекомендовал это в любом производственном коде, это решение "на свой страх и риск".

import mymodule

with open(os.path.splitext(mymodule.__file__)[0] + ".py") as fh:
    exec fh.read()

Ответ 2

Как указано в других ответах, это плохая идея, и вы должны решить эту проблему по-другому.

Независимо от того, как Python делает это так:

import runpy
result = runpy._run_module_as_main("your.module.name"))

Ответ 3

Поместите этот код в функцию и вызовите его из модуля, в который вы его импортируете.

def stuff():
    ...

if __name__ == '__main__':
    stuff()

И затем в модуле вы импортируете его в:

import module
module.stuff()

Ответ 4

Поместите его в функцию:

def _main():
   do stuff

if __name__ == '__main__':
    main()

Ответ 5

Код в главной строфе обычно никогда не имеет смысла запускать напрямую. Если вы хотите запустить его, используйте subprocess, чтобы запустить его в другом интерпретаторе Python.

Ответ 6

Вот пример основного модуля в Python:

#! /usr/bin/env python
import sys
import os

def main(arg1, arg2, arg3):
    print(arg1, arg2, arg3)

if __name__ == "__main__":
    main(*sys.argv)

Но вы также можете включить

def main():
   #The module contains Python code specific to the library module, 
   #like tests, and follow the module with this:

if __name__ == "__main__":
    main(*sys.argv)

в любом модуле, который вы хотели бы запустить как основной.

Например, если у вас есть библиотечный модуль, вы всегда можете использовать эту конструкцию для выполнения каких-то конкретных тестов.