Почему Python запускает мой модуль, когда я импортирую его, и как мне его остановить? - PullRequest
137 голосов
/ 29 июня 2011

У меня есть программа на Python, которую я создаю и которую можно запустить любым из двух способов: во-первых, вызвать "python main.py", который предлагает пользователю ввести данные дружественным образом, а затем запускает пользовательский ввод через программа. Другой способ - вызвать "python batch.py ​​ -file- ", который пропустит весь дружественный сбор ввода и выполнит ввод всего файла за одну программу.

Проблема в том, что когда я запускаю "batch.py", он импортирует некоторые переменные / методы / и т. Д. Из "main.py", и когда он запускает этот код:

import main

в первой строке программы, она сразу же выдает ошибку, потому что пытается запустить код в "main.py".

Как я могу остановить запуск Python кода, содержащегося в "основном" модуле, который я импортирую?

Ответы [ 9 ]

205 голосов
/ 29 июня 2011

Поскольку именно так работает Python - такие ключевые слова, как class и def, являются , а не объявлениями . Вместо этого они являются настоящими живыми операторами , которые выполняются. Если бы они не были выполнены, ваш модуль был бы .. пустым: -)

В любом случае, идиоматический подход:

# stuff to run always here such as class/def
def main():
    pass

if __name__ == "__main__":
   # stuff only to run when not called via 'import' here
   main()

См. Для чего if __name__ == "__main__"? 1014 *

Однако требуется контроль источника над модулем import ed.

Удачного кодирования.

45 голосов
/ 29 июня 2011

В связи с тем, как работает Python, ему необходимо запускать ваши модули при их импорте.

Чтобы запретить выполнение кода в модуле при импорте, но только при непосредственном запуске, вы можетеЗащитите его этим if:

if __name__ == "__main__":
    # this won't be run when imported

Возможно, вы захотите поместить этот код в метод main(), чтобы вы могли либо выполнить файл напрямую, либо импортировать модуль и вызвать main().Например, предположим, что это в файле foo.py.

def main():
    print "Hello World"

if __name__ == "__main__":
    main()

Эта программа может быть запущена либо с помощью команды python foo.py, либо из другого скрипта Python:

import foo

...

foo.main()
11 голосов
/ 29 июня 2011

Используйте if __name__ == '__main__' идиома - __name__ - это специальная переменная, значение которой '__main__', если модуль запускается как скрипт, и имя модуля, если он импортирован. Так что вы бы сделали что-то вроде

# imports
# class/function definitions
if __name__ == '__main__':
    # code here will only run when you invoke 'python main.py'
4 голосов
/ 11 марта 2014

Поместите код в функцию, и он не будет работать, пока вы не вызовете функцию. У вас должна быть основная функция в вашем main.py. с утверждением:

if __name__ == '__main__':
  main()

Затем, если вы вызовете python main.py, будет запущена функция main(). Если вы импортируете main.py, это не так. Кроме того, для ясности вам, вероятно, следует переименовать main.py во что-то другое.

4 голосов
/ 29 июня 2011

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

Поскольку у вас, вероятно, есть доступ к файлу, вы можете посмотреть, что является причиной ошибки. Может быть возможно изменить вашу среду, чтобы предотвратить возникновение ошибки.

2 голосов
/ 29 июня 2011

Вы можете написать свой "main.py" так:

#!/usr/bin/env python

__all__=["somevar", "do_something"]

somevar=""

def do_something():
    pass #blahblah

if __name__=="__main__":
    do_something()
1 голос
/ 25 марта 2015

Было предложение по улучшению Python PEP 299 , целью которого было заменить идиому if __name__ == '__main__': на def __main__:, но оно было отклонено.Это все еще хорошее чтение, чтобы знать, что следует иметь в виду при использовании if __name__ = '__main__':.

0 голосов
/ 17 июня 2014

Хотя вы не можете использовать import без запуска кода;есть довольно быстрый способ ввода переменных;используя numpy.savez, который хранит переменные в виде пустых массивов в файле .npz.После этого вы можете загрузить переменные, используя numpy.load.

См. Полное описание в документации scipy

Обратите внимание, что это касается только переменных и массивов переменных, а не методов и т. Д.

0 голосов
/ 29 июня 2011

Попробуйте просто импортировать нужные функции из main.py?Итак,

from main import SomeFunction

Возможно, вы назвали функцию в batch.py ​​так же, как функцию в main.py, и при импорте main.py программа запускает функцию main.pyфункции batch.py;выполнение вышеупомянутого должно исправить это.Я надеюсь.

...