Что делать, если __name__ == "__main__": делать?

3314
голосов

Что делает if __name__ == "__main__":?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while 1:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)
if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
задан Devoted 07 янв. '09 в 7:11
источник

19 ответов

3634
голосов

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

Перед выполнением кода он определит несколько специальных переменных. Например, если интерпретатор python запускает этот модуль (исходный файл) в качестве основной программы, он устанавливает специальную переменную __name__ для значения "__main__". Если этот файл импортируется из другого модуля, __name__ будет присвоено имя модуля.

В случае вашего script предположим, что он выполняет роль основной функции, например. вы сказали что-то вроде

python threading_example.py

в командной строке. После настройки специальных переменных он выполнит оператор import и загрузит эти модули. Затем он будет оценивать блок def, создавая объект функции и создавая переменную с именем myfunction, которая указывает на объект функции. Затем он прочитает инструкцию if и увидит, что __name__ делает равным "__main__", поэтому он выполнит показанный там блок.

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

Подробнее см. эту страницу.

ответ дан Mr Fooz 07 янв. '09 в 7:26
источник
1078
голосов

Когда ваш script запускается, передавая его как команду интерпретатору Python,

python myscript.py

выполняется весь код, который находится на уровне отступа 0. Определенные функции и классы определены, но не определены, но ни один из их кодов не запускается. В отличие от других языков нет функции main(), которая запускается автоматически - функция main() неявно содержит весь код на верхнем уровне.

В этом случае код верхнего уровня представляет собой блок if. __name__ - встроенная переменная, которая оценивает имя текущего модуля. Однако, если модуль запускается напрямую (как в myscript.py выше), то вместо __name__ устанавливается строка "__main__". Таким образом, вы можете проверить, выполняется ли ваш script напрямую или импортируется чем-то другим, тестируя

if __name__ == "__main__":
    ...

Если ваш script импортируется в другой модуль, его различные определения функций и классов будут импортированы, а его код верхнего уровня будет выполнен, но код в том же тесте выше if выше выиграл 'get get, поскольку условие не выполняется. В качестве базового примера рассмотрим следующие два сценария:

# file one.py
def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Теперь, если вы вызываете интерпретатор как

python one.py

Выход будет

top-level in one.py
one.py is being run directly

Если вы запустите two.py:

python two.py

Вы получаете

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

Таким образом, когда модуль one загружается, его __name__ равно "one" вместо __main__.

ответ дан Adam Rosenfield 07 янв. '09 в 7:28
источник
464
голосов

Простейшим объяснением для переменной __name__ (imho) является следующее:

Создайте следующие файлы.

# a.py
import b

и

# b.py
print "Hello World from %s!" % __name__

if __name__ == '__main__':
    print "Hello World again from %s!" % __name__

Запуск их даст вам этот результат:

$ python a.py
Hello World from b!

Как вы можете видеть, когда модуль импортируется, Python устанавливает globals()['__name__'] в этом модуле имя модуля.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

Как вы можете видеть, когда файл выполняется, Python устанавливает globals()['__name__'] в этом файле на "__main__".

ответ дан pi. 07 янв. '09 в 14:35
источник
356
голосов

Что делает if __name__ == "__main__":?

Глобальная переменная __name__ в модуле, являющемся точкой входа в вашу программу, составляет '__main__'.

Итак, код в этом блоке if будет запущен, только если этот модуль является точкой входа в вашу программу.


Зачем нам это нужно?

Разработка и тестирование кода

Предположим, вы пишете Python script, предназначенный для использования в качестве модуля:

def do_important():
    """This function does something very important"""

Вы можете протестировать модуль, добавив этот вызов функции в нижнюю часть:

do_important()

и запустив его (в командной строке) с чем-то вроде:

~$ python important.py

Проблема

Однако, если вы хотите импортировать модуль в другой script:

import important

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

Лучший способ

Переменная __name__ указывает на пространство имен везде, где в настоящий момент интерпретатор Python находится. Внутри импортированного модуля это имя этого модуля. Но внутри первичного модуля (или интерактивного сеанса Python, т.е. Интерпретатора Read, Eval, Print Loop или REPL) вы запускаете все, начиная с "__main__".

Итак, если вы проверите перед выполнением:

if __name__ == "__main__":
    do_important()

При вышесказанном ваш код будет выполняться только в том случае, если вы используете его в качестве основного модуля (или намеренно вызываете его из другого script).

Еще лучший способ

Там есть питоновский способ улучшить это.

Что делать, если мы хотим запустить этот бизнес-процесс извне модуля? Если мы поместим код, который хотим реализовать по мере разработки и тестирования в такой функции, а затем сделаем нашу проверку для '__main__' сразу после:

def main():
    """business logic for when running this module as the primary one!"""
    setup()
    foo = do_important()
    bar = do_even_more_important(foo)
    for baz in bar:
        do_super_important(baz)
    teardown()

# Here our payoff idiom!
if __name__ == '__main__':
    main()

Теперь у нас есть окончательная функция для конца нашего модуля, которая будет работать, если мы запустим модуль как первичный модуль. Это позволит модулю и его функциям и классам импортироваться в другие сценарии без использования функции main, а также позволяет вызывать модуль (и его функции и классы) при работе из другого модуля '__main__' то есть

import important
important.main()

Эта идиома также может быть найдена в документации Python в объяснении модуля __main__. В этом тексте указано:

Этот модуль представляет (в противном случае анонимную) область, в которой основная программа интерпретаторов - команды, читаемые либо из стандартный ввод, из файла script или из интерактивной подсказки. Это это среда, в которой идиоматическая "условная script" строфа вызывает запуск script:

if __name__ == '__main__':
    main()
ответ дан Aaron Hall 23 нояб. '13 в 7:38
источник
83
голосов

if __name__ == "__main__" - это часть, которая выполняется, когда script запускается из (скажем) командной строки с помощью команды типа python myscript.py.

ответ дан Harley Holcombe 07 янв. '09 в 7:14
источник
48
голосов

Что делает if __name__ == "__main__":?

__name__ - глобальная переменная (в Python глобальная на самом деле означает на уровне уровень модуля), который существует во всех пространствах имен. Обычно это имя модуля (как тип str).

Как единственный частный случай, однако, в любом запущенном процессе Python, как в mycode.py:

python mycode.py

иначе анонимному глобальному пространству имен присваивается значение '__main__' его __name__.

Таким образом, включая окончательные строки

if __name__ == '__main__':
    main()
  • в конце mycode.py script,
  • когда он является основным модулем начальной точки, который запускается процессом Python,

приведет к выполнению уникальной функции main script.

Еще одно преимущество использования этой конструкции: вы также можете импортировать свой код в качестве модуля в другой script, а затем запустить основную функцию, если и когда ваша программа решит:

import mycode
# ... any amount of other code
mycode.main()
ответ дан Aaron Hall 14 окт. '14 в 23:22
источник
32
голосов

Если в нашем модуле (M.py) есть определенные операторы, мы хотим выполнить их, когда он будет запущен как основной (не импортированный), в этом случае мы можем разместить эти утверждения (тестовые примеры, заявления печати ) в этом блоке if. По умолчанию (когда модуль работает как основной, а не импортирован) переменная __name__ установлена ​​на "__main__", и когда она будет импортирована, переменная __name__ получит другое значение, скорее всего, имя модуль ('M'). Это полезно при совместном использовании разных вариантов модулей и разделении их конкретных инструкций ввода и вывода, а также в случае любых тестовых случаев.

Короче, используйте этот блок if __name__ == "main" для предотвращения (определенного) кода при импорте модуля.

ответ дан Nabeel Ahmed 03 апр. '13 в 17:09
источник
27
голосов

Давайте рассмотрим ответ более абстрактным образом:

Предположим, что этот код есть в x.py:

...
<Block A>
if __name__ == '__main__':
    <Block B>
...

Блоки A и B запускаются, когда мы запускаем "x.py".

Но только блок A (а не B) запускается, когда мы запускаем другой модуль, например "y.py", в котором xy импортируется и код запускается оттуда (например, когда функция в "x". py "вызывается из y.py).

ответ дан Alisa 20 янв. '15 в 20:48
источник
26
голосов

При запуске Python в интерактивном режиме локальной переменной __name__ присваивается значение __main__. Аналогично, когда вы выполняете модуль Python из командной строки, а не импортируете его в другой модуль, атрибуту __name__ присваивается значение __main__, а не фактическое имя модуля. Таким образом, модули могут посмотреть свое собственное значение __name__, чтобы определить для себя, как они используются, будь то поддержка другой программы или основного приложения, выполняемого из командной строки. Таким образом, следующая идиома довольно распространена в модулях Python:

if __name__ == '__main__':
    # Do something appropriate here, like calling a
    # main() function defined elsewhere in this module.
    main()
else:
    # Do nothing. This module has been imported by another
    # module that wants to make use of the functions,
    # classes and other useful bits it has defined.
ответ дан Zain 11 дек. '13 в 14:23
источник
23
голосов

Здесь много разных аспектов механики рассматриваемого кода, "Как", но для меня это не имело смысла, пока я не понял "Почему". Это должно быть особенно полезно для новых программистов.

Возьмем этот пример:

Файл "ab.py":

def a():
    print('A function in ab file');
a()

Второй файл "xy.py":

import ab
def main():
    print('main function')
def x(): 
    print ('s')
x()
if __name__ == "__main__":
    main()

Что делает этот код на самом деле?

При выполнении xy.py вы импортируете ab. Оператор import запускает модуль сразу при импорте, поэтому операции ab выполняются до остальной части xy. Закончив с ab, он продолжит с xy.

Интерпретатор отслеживает, какие сценарии работают с __name__. Когда вы запускаете script - независимо от того, что вы его назвали, интерпретатор называет его "__main__". Это то, как он отслеживает, какой script является основным файлом, script, который возвращается после внешнего вызова другому script. (Можно сказать, что "домашний" script.) Любой другой script, вызываемый из этого "основного" script, присваивает свое имя файла своему __name__. Следовательно, строка if __name__ == "__main__": - это тест-интерпретатор, чтобы определить, работает ли он на script, на котором он смотрит (разбор), или если он временно заглянет в другой script. Это дает гибкость программиста, чтобы script вел себя по-другому, если он вызвал внешне.

Чтобы понять, что происходит, сначала сосредоточьтесь на незаметных строках и порядке, которые они отображают в сценариях. Помните, что функции - или def - блоки ничего не делают сами по себе, пока не будут вызваны. Что может интерпретировать интерпретатор, если пробормотал себе:

  • Открыть xy.py. Хорошо, xy.py является "домашним" файлом; это означает, что он получает название "__main__" в переменной __name__.
  • Импортировать и открыть файл с помощью __name__ ab.py.
  • О, функция. Я запомню это.
  • Хорошо, функция a(); Я только что узнал об этом. Думаю, теперь я буду печатать.
  • Конец файла; вернуться к "__main__"!
  • О, функция. Я запомню это.
  • Другой.
  • Функция x(); ok, print 's'.
  • Что это? Оператор if. Ну, условие выполнено (переменная __name__ установлена ​​на "__main__"), поэтому я буду вводить функцию main() и печатать "главную функцию".

Нижние две строки означают: "Если это" основной "или" домашний "script, выполните функцию с именем main(). Поэтому вы увидите блок def main(): вверху, который содержит основной поток функциональности script.

Зачем это реализовать?

Помните, что я сказал ранее об операциях импорта? При импорте модуля он не просто "распознает" его и ждет дальнейших инструкций - он фактически выполняет все исполняемые операции, содержащиеся в script. Таким образом, добавление мяса вашего script в функцию main() эффективно помещает его в карантин, помещая его изолированно, чтобы он не запускался сразу при импорте с помощью другого script.

Опять же, будут исключения, но обычной практикой является то, что main() обычно не вызывает вызов извне. Поэтому вам может быть интересно еще одно: если мы не вызываем main(), почему мы вообще вызываем script? Это потому, что многие люди строят свои скрипты с автономными функциями, которые создаются для самостоятельной работы. Затем их затем вызывают в другом месте в теле script. Это подводит меня к этому:

Но код работает без него

Да, это правильно. Эти отдельные функции могут вызываться из строки script, которая не содержится внутри функции main(). Если вы привыкли (как и я, на ранних этапах программирования) к созданию встроенных сценариев, которые делают именно то, что вам нужно, и вы попытаетесь выяснить это снова, если вам понадобится эта операция снова. ну, вы не привыкли к такой внутренней структуре вашего кода, потому что это сложнее построить, и это не так просто интуитивно понятно. Но что script, который, вероятно, не может иметь свои функции, вызванные извне, потому что если бы он это сделал, он начал бы вычислять и присваивать переменные. И, скорее всего, если вы пытаетесь повторно использовать функцию, ваш новый script связан достаточно близко со старым, что могут быть конфликтующие переменные.

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

ответ дан joechoj 29 сент. '16 в 7:33
источник
21
голос

Put Simply __name__ - это переменная, определенная для каждого script, которая определяет, выполняется ли script в качестве основного модуля или запускается как импортированный модуль.

Итак, если у нас есть два сценария;

#script1.py
print "Script 1 name: {}".format(__name__)

и;

#script2.py
import script1
print "Script 2 name: {}".format(__name__)

Результат выполнения сценария1:

Script 1 name: __main__

а результат выполнения скрипта2:

Script1 name is script1 
Script 2 name: __main__

Как вы можете видеть; __name__ указывает, какой код является "основным" модулем. Это здорово, потому что вы можете просто писать код и не беспокоиться о структурных проблемах, как в C/С++, где, если файл не реализует "главную" функцию, он не может быть скомпилирован как исполняемый файл, и если это так, не может использоваться в качестве библиотеки.

Скажем, вы пишите python script, который делает что-то отличное, и вы реализуете лодку функций, полезных для других целей, если я хочу их использовать, я могу просто импортировать ваш script и использовать их без выполнения вашей программы (учитывая, что ваш код выполняется только в контексте if __name__ == "__main__":). Если в C/С++ вам придется разделить эти фрагменты на отдельный модуль, который затем включает файл. Представьте ситуацию ниже;

сложный импорт в C

Стрелки - это ссылки импорта. Для трех модулей, каждый из которых пытается включить код предыдущих модулей, есть шесть файлов (девять, считая файлы реализации) и пять ссылок, это затрудняет включение другого кода в проект c, если он не скомпилирован специально как библиотека. Теперь представьте его для python;

элегантный импорт в Python

Вы пишете модуль. Если кто-то хочет использовать ваш код, он просто импортирует его, а переменная __name__ может отделить исполняемую часть программы от части библиотеки.

ответ дан redbandit 15 окт. '16 в 12:07
источник
15
голосов

Это особенность, когда из командной строки вызывается файл Python. Обычно это используется для вызова функции "main()" или для запуска другого соответствующего кода запуска, например, для обработки аргументов командной строки.

Он может быть написан несколькими способами, а другой -

def main():
    dosomething()


__name__ == '__main__' and main()

Я не говорю, что вы должны использовать это в производственном коде, но это служит для иллюстрации того, что в if __name__ == '__main__' нет ничего "волшебного". Это (большое!) Соглашение для вызова основной функции в файлах Python.

ответ дан Prof. Falken 24 янв. '13 в 16:48
источник
15
голосов
if __name__ == "__main__":
    main()

Проверяет, является ли атрибут __name__ для python script "__main__". Другими словами, если сама программа выполнена, атрибут будет __main__, поэтому программа будет выполнена (в этом случае функция main()).

Однако, если ваш python script используется модулем, будет выполняться любой код вне оператора if, поэтому, если __name__ == "__main__" используется только для проверки того, используется ли программа в качестве модуля или нет, и поэтому решает, следует ли запускать код.

ответ дан Larry 22 авг. '17 в 21:53
источник
14
голосов

Существует ряд переменных, которые система (интерпретатор Python) предоставляет исходные файлы (модули). Вы можете получить их значения в любое время, поэтому, давайте сосредоточимся на __ name __ переменной/атрибуте:

Когда Python загружает файл исходного кода, он выполняет весь найденный в нем код. (Обратите внимание, что он не вызывает все методы и функции, определенные в файле, но определяет их.)

Прежде чем интерпретатор выполнит файл исходного кода, он определяет несколько специальных переменных для этого файла; __ name __ - одна из тех специальных переменных, которые Python автоматически определяет для каждого файла исходного кода.

Если Python загружает этот файл исходного кода в качестве основной программы (т.е. файл, который вы запускаете), тогда он устанавливает специальную переменную __ name __ для этого файла, имеющую значение "__ main__" .

Если это импортируется из другого модуля, __ name __ будет установлено это имя модуля.

Итак, в вашем примере отчасти:

if __name__ == "__main__":
   lock = thread.allocate_lock()
   thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
   thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

означает, что блок кода:

lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

будет выполняться только при непосредственном запуске модуля; блок кода не будет выполняться, если другой модуль вызывает/импортирует его, потому что значение __ name __ не будет равно " main" в этом конкретном экземпляре.

Надеюсь, что это поможет.

ответ дан codewizard 25 нояб. '15 в 15:26
источник
10
голосов

Я думаю, что лучше всего разбить ответ в глубине и простыми словами:

__ name __: каждый модуль в Python имеет специальный атрибут __name__. Это встроенная переменная, которая возвращает имя модуля.

__ main __. Как и другие языки программирования, Python тоже имеет точку входа для выполнения, т.е. main. " main" - это имя области, в которой выполняется код верхнего уровня. В принципе у вас есть два способа использования модуля Python: запустите его непосредственно как script или импортируйте. Когда модуль запускается как script, его __name__ устанавливается на __main__.

Таким образом, значение атрибута __name__ устанавливается на __main__, когда модуль запускается как основная программа. В противном случае значение __name__ будет содержать имя модуля.

ответ дан Inconnu 30 нояб. '16 в 9:47
источник
10
голосов

, если __name__ == "__main __": - это в основном среда верхнего уровня script, она указывает интерпретатор, который ( "У меня есть наивысший приоритет, который нужно выполнить первым" ).

'__ main __' - это имя области, в которой выполняется код верхнего уровня. При чтении со стандартного ввода, script или из интерактивного приглашения модули имя установлено равным main.

if __name__ == "__main__":
    # execute only if run as a script
    main()
ответ дан The Gr8 Adakron 24 апр. '16 в 11:23
источник
4
голосов

Вы можете сделать файл полезным как script, а также импортируемый модуль.

fibo.py(модуль с именем fibo)

# Other modules can IMPORT this MODULE to use the function fib
def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()

# This allows the file to be used as a SCRIPT
if __name__ == "__main__":
    import sys
    fib(int(sys.argv[1]))

Ссылка: https://docs.python.org/3.5/tutorial/modules.html

ответ дан sam 14 марта '17 в 0:44
источник
4
голосов
print __name__

для вышеприведенного значения main

if __name == "__main__":
  print direct method

приведенный выше оператор получает значение true и метод прямой печати предполагает, что если они импортировали этот класс в другой класс, он не печатает прямой метод. Потому что при импорте он установит __name__ == "firstmodel name"

ответ дан Janarthanan Ramu 22 июня '16 в 13:47
источник
3
голосов

Причина

if __name__ == "__main__":
    main()

заключается прежде всего в том, чтобы избежать блокировки импорта, которые возникли бы из с кодом, непосредственно импортированным.

Побочным эффектом является то, что вы автоматически подписываетесь на методологию, которая поддерживает несколько точек входа.

ответ дан personal_cloud 22 сент. '17 в 21:32
источник

Другие вопросы по меткам