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

Что делает if __name__ == "__main__": с учетом следующего кода?

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        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))

person Devoted    schedule 07.01.2009    source источник
comment
Для записи - что такое main: docs.python.org/3/reference/ и что такое name: docs.python.org/3/reference/   -  person bruziuz    schedule 02.04.2021


Ответы (38)


Короткий ответ

Это шаблонный код, который защищает пользователей от случайного вызова сценария, когда они этого не собирались. Вот некоторые типичные проблемы, возникающие при отсутствии защиты в скрипте:

  • Если вы импортируете скрипт без защиты в другой скрипт (например, import my_script_without_a_name_eq_main_guard), то второй скрипт инициирует запуск первого во время импорта и с использованием аргументов командной строки второго скрипта. Это почти всегда ошибка.

  • Если у вас есть собственный класс в сценарии без защиты и вы сохранили его в файле pickle, то его извлечение в другом сценарии вызовет импорт сценария без защиты с теми же проблемами, что описаны в предыдущем пункте.

Длинный ответ

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

Всякий раз, когда интерпретатор Python читает исходный файл, он делает две вещи:

  • он устанавливает несколько специальных переменных, например __name__, а затем

  • он выполняет весь код, найденный в файле.

Давайте посмотрим, как это работает и как это связано с вашим вопросом о __name__ проверках, которые мы всегда видим в скриптах Python.

Образец кода

Давайте воспользуемся немного другим примером кода, чтобы изучить, как работают импорт и скрипты. Предположим, следующее находится в файле с именем foo.py.

# Suppose this is foo.py.

print("before import")
import math

print("before functionA")
def functionA():
    print("Function A")

print("before functionB")
def functionB():
    print("Function B {}".format(math.sqrt(100)))

print("before __name__ guard")
if __name__ == '__main__':
    functionA()
    functionB()
print("after __name__ guard")

Специальные переменные

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

Когда ваш модуль является основной программой

Если вы запускаете свой модуль (исходный файл) в качестве основной программы, например

python foo.py

интерпретатор назначит жестко запрограммированную строку "__main__" переменной __name__, т. е.

# It's as if the interpreter inserts this at the top
# of your module when run as the main program.
__name__ = "__main__" 

Когда ваш модуль импортирован другим

С другой стороны, предположим, что основной программой является какой-то другой модуль, который импортирует ваш модуль. Это означает, что в основной программе или в каком-либо другом модуле, импортируемом основной программой, есть такой оператор:

# Suppose this is in some other main program.
import foo

Интерпретатор будет искать ваш foo.py файл (наряду с поиском нескольких других вариантов) и перед выполнением этого модуля присвоит переменной __name__ имя "foo" из оператора импорта, т. Е.

# It's as if the interpreter inserts this at the top
# of your module when it's imported from another module.
__name__ = "foo"

Выполнение кода модуля

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

Всегда

  1. Он печатает строку "before import" (без кавычек).

  2. Он загружает модуль math и назначает его переменной с именем math. Это эквивалентно замене import math следующим (обратите внимание, что __import__ - это функция низкого уровня в Python, которая принимает строку и запускает фактический импорт):

# Find and load a module given its string name, "math",
# then assign it to a local variable called math.
math = __import__("math")
  1. Он печатает строку "before functionA".

  2. Он выполняет блок def, создает объект функции, а затем назначает этот объект функции переменной с именем functionA.

  3. Он печатает строку "before functionB".

  4. Он выполняет второй блок def, создавая другой объект функции, а затем присваивая его переменной с именем functionB.

  5. Он печатает строку "before __name__ guard".

Только тогда, когда ваш модуль является основной программой

  1. Если ваш модуль является основной программой, он увидит, что __name__ действительно установлен на "__main__", и вызовет две функции, распечатав строки "Function A" и "Function B 10.0".

Только когда ваш модуль импортирован другим

  1. (Вместо этого). Если ваш модуль не является основной программой, но был импортирован другой программой, тогда __name__ будет "foo", а не "__main__", и он пропустит тело оператора if.

Всегда

  1. В обоих случаях он напечатает строку "after __name__ guard".

Резюме

Таким образом, вот что будет напечатано в двух случаях:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __name__ guard
Function A
Function B 10.0
after __name__ guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __name__ guard
after __name__ guard

Почему это так работает?

Вы, естественно, можете задаться вопросом, зачем кому-то это нужно. Ну, иногда вы хотите написать .py файл, который может использоваться другими программами и / или модулями как модуль, а также может запускаться как сама основная программа. Примеры:

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

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

  • Ваш модуль в основном используется как основная программа, но он также предоставляет удобный для программиста API для опытных пользователей.

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

Пища для размышлений

  • Вопрос: Могу ли я иметь несколько __name__ проверочных блоков? Ответ: это странно, но язык вас не остановит.

  • Предположим, следующее находится в foo2.py. Что произойдет, если вы скажете python foo2.py в командной строке? Почему?

# Suppose this is foo2.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
print("t2")
      
  • Теперь выясните, что произойдет, если вы уберете __name__ проверку в foo3.py:
# Suppose this is foo3.py.
import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

def functionB():
    print("b")

print("t1")
print("m1")
functionA()
print("m2")
print("t2")
  • Что это будет делать при использовании в качестве сценария? При импорте в виде модуля?
# Suppose this is in foo4.py
__name__ = "__main__"

def bar():
    print("bar")
    
print("before __name__ guard")
if __name__ == "__main__":
    bar()
print("after __name__ guard")
person Mr Fooz    schedule 07.01.2009
comment
Из любопытства: что произойдет, если я запустил subprocess.run('foo_bar.py') в скрипте Python? Я полагаю, что foo_bar будет запущен с __name__ = '__main__', как когда я набираю foo_bar.py в cmd вручную. Так ли это? Принимая во внимание ответ @MrFooz, не должно возникнуть никаких проблем с этим и с тем, чтобы одновременно иметь столько основных модулей, сколько мне нравится. Даже изменение значения __name__ или наличие нескольких экземпляров, созданных независимо друг от друга (или экземпляров, созданных subprocess), взаимодействующих друг с другом, должно быть обычным делом для Python. Я что-то упускаю? - person hajef; 18.02.2019
comment
@hajef Вы правы насчет того, как все будет работать с subprocess.run. Тем не менее, как правило, лучший способ совместного использования кода между сценариями - это создавать модули и заставлять сценарии вызывать общие модули вместо того, чтобы вызывать друг друга как сценарии. Трудно отлаживать subprocess.run вызовы, поскольку большинство отладчиков не пересекают границы процессов, они могут добавить нетривиальные системные издержки для создания и уничтожения дополнительных процессов и т. Д. - person Mr Fooz; 19.02.2019
comment
У меня есть сомнения по поводу примера foo2.py в разделе пищи для размышлений. что делает from foo2.py import functionB? На мой взгляд, он просто импортирует foo2.py из functionB - person user471651; 24.02.2019
comment
@MrFooz Я никогда не собирался делать что-то подобное xD Это просто пришло мне в голову, и я понял, что это было достаточно странно, чтобы, возможно, помочь людям. обдумывают подобные вещи. @ user471651 Зачем from foo2 import functionB импортировать foo2 из functionB? Это семантическое искажение. from module import method импортирует метод из модуля. - person hajef; 25.02.2019
comment
Одним из модулей, которые могут импортировать ваш код, является multiprocessing, в частности, делая этот тест необходимым в Windows. - person Yann Vernier; 17.09.2019
comment
Крайне незначительный момент, но я считаю, что python фактически определяет __name__ импортированного модуля из оператора импорта, а не путем удаления .py из имени файла. Поскольку идентификаторы python чувствительны к регистру, а имена файлов могут не учитываться (например, в Windows), в имени файла не обязательно содержится достаточно информации, чтобы определить правильное имя модуля python. - person Ben; 04.02.2020
comment
@ Бен Спасибо. Сообщение обновлено. Я не стал искать реальный код для описываемой вами логики, но это правда. - person Mr Fooz; 06.02.2020
comment
@ user471651 В разделе "Пища для размышлений" from foo2 import functionB заставит интерпретатор Python перезагрузить foo2.py во второй раз, но на этот раз он будет иметь __name__='foo2' вместо __name__='__main__'. В ОЗУ будет две копии functionB. functionA в __main__ будет вызывать версию, загруженную как foo2.functionB, а не копию __main__.functionB. - person Mr Fooz; 31.03.2020
comment
Тогда как это относится к __main__.py. - person BAKE ZQ; 12.06.2020
comment
Почему я получаю сообщение об ошибке - ModuleNotFoundError: нет модуля с именем 'functionB' при запуске foo2.py и foo3.py? - person Vaibhav Gupta; 22.06.2020
comment
@VaibhavGupta Вы, вероятно, используете интерпретатор, который не добавляет автоматически каталог сценария в sys.path. Функция автоматического добавления существует уже давно (навсегда?) И упрощает использование Python, но она небезопасна. Для повышения безопасности некоторые люди отключают эту функцию. У меня возникли проблемы с нахождением публичной записи об этом, но недавно были дискуссии об удалении функции автоматического добавления из Python 3. Может быть, это действительно произошло сейчас. Тем не менее, я добавил строку, которая должна заставить foo2.py и foo3.py работать для более безопасной настройки интерпретатора. - person Mr Fooz; 23.06.2020
comment
Мне понравилось, как тонко эта строка решила мою путаницу: запуск сценария - это побочный эффект импорта модуля сценария. - person Abhimanyu Shekhawat; 09.09.2020
comment
Как вы написали этот подробный ответ через 15 минут после того, как его спросили? - person Chad P; 08.01.2021
comment
@ChadP Этот пост развивался со временем в ответ на обсуждение здесь, в комментариях. В 2019 году StackOverflow удалил все комментарии. Вы можете увидеть полную историю этого сообщения, нажав на отредактированную ссылку ‹timestamp› прямо над этим разделом комментариев. StackOverflow - это круто. К сожалению, я не думаю, что есть способ вернуть старые удаленные комментарии. - person Mr Fooz; 13.01.2021
comment
Для тех, кто интересуется бесконечным циклом, см. это - person vbenara; 08.03.2021
comment
@ V.ben В самом деле. Если вам интересно, то способ, которым Python обеспечивает однократную загрузку модулей, - это запоминание объектов модуля в sys.modules. Ближе к началу импорта проверяет, зарегистрирован ли там модуль; если да, то он останавливается. В противном случае он создает пустой объект-модуль и немедленно внедряет его в sys.modules. После этого он начинает выполнение кода модуля, как описано в этом посте. - person Mr Fooz; 09.03.2021

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

python myscript.py

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

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

if __name__ == "__main__":
    ...

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

# 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__".

person Adam Rosenfield    schedule 07.01.2009
comment
Итак, if __name__ == "__main__": в основном проверяет, запускаете ли вы свой скрипт python, а не импортируете его или что-то в этом роде? - person Merp; 18.02.2021

Самое простое объяснение переменной __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__'] в этом модуле на имя модуля. Кроме того, при импорте выполняется весь код модуля. Поскольку оператор if оценивается как False, эта часть не выполняется.

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

Как видите, при выполнении файла Python устанавливает globals()['__name__'] в этом файле на "__main__". На этот раз оператор if оценивается как True и выполняется.

person pi.    schedule 07.01.2009

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

Чтобы изложить основы:

  • Глобальная переменная __name__ в модуле, который является точкой входа в вашу программу, - это '__main__'. В противном случае это имя, под которым вы импортируете модуль.

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

  • Это позволяет импортировать код в модуле другими модулями без выполнения блока кода ниже при импорте.


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

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

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

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

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

do_important()

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

~$ python important.py

Эта проблема

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

import important

При импорте будет вызвана функция do_important, поэтому вы, вероятно, закомментируете вызов функции do_important() внизу.

# do_important() # I must remember to uncomment to execute this!

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

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

Переменная __name__ указывает на пространство имен, где интерпретатор Python находится в данный момент.

Внутри импортированного модуля это имя этого модуля.

Но внутри основного модуля (или интерактивного сеанса Python, т.е. интерпретатора Read, Eval, Print Loop или REPL) вы запускаете все из его "__main__".

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

if __name__ == "__main__":
    do_important()

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

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

Тем не менее, есть способ Pythonic улучшить это.

Что, если мы хотим запустить этот бизнес-процесс извне модуля?

Если мы поместим код, который мы хотим использовать при разработке и тестировании, в такой функции, а затем проведем нашу проверку на '__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's our payoff idiom!
if __name__ == '__main__':
    main()

Теперь у нас есть последняя функция для конца нашего модуля, которая будет запущена, если мы запустим модуль как основной.

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

import important
important.main()

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

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

if __name__ == '__main__':
    main()
person Aaron Hall    schedule 23.11.2013

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

person Harley Holcombe    schedule 07.01.2009
comment
Почему файл helloworld.py, содержащий только print("hello world"), может работать с командой python helloworld.py, даже если нет if __name__ == "__main__"? - person hi15; 22.08.2019
comment
Когда вы запускаете python helloworld.py, он запускает весь файл сценария (независимо от того, указываете вы if __name__ == "__main__" или нет). Есть разница только в исполнении, когда вы импортируете helloworld.py из другого скрипта. В этом случае кодовый блок if __name__ == "__main__" вообще не выполняется. - person Nihal Sangeeth; 29.12.2020

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

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

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

python mycode.py

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

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

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

вызовет выполнение уникально определенной функции main вашего скрипта.

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

import mycode
# ... any amount of other code
mycode.main()
person Aaron Hall    schedule 14.10.2014

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

Возьмем файл "ab.py":

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

И второй файл «xy.py»:

import ab
def main():
    print('main function: this is where the action is')
def x():
    print ('peripheral task: might be useful in other projects')
x()
if __name__ == "__main__":
    main()

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

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

Интерпретатор отслеживает, какие скрипты выполняются с __name__. Когда вы запускаете сценарий - независимо от того, как вы его называете - интерпретатор называет его "__main__", делая его главным или «домашним» сценарием, который возвращается после запуска внешнего сценария.

Любому другому сценарию, который вызывается из этого "__main__" сценария, присваивается имя его файла __name__ (например, __name__ == "ab.py"). Следовательно, строка if __name__ == "__main__": - это тест интерпретатора, чтобы определить, интерпретирует ли он / анализирует «домашний» скрипт, который был первоначально выполнен, или он временно просматривает другой (внешний) скрипт. Это дает программисту гибкость в том, чтобы сценарий вел себя иначе, если он выполняется напрямую, а не вызывается извне.

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

  • Откройте xy.py как «домашний» файл; назовите его "__main__" в переменной __name__.
  • Импортируйте и откройте файл с расширением __name__ == "ab.py".
  • О, функция. Я это запомню.
  • Хорошо, функция a(); Я только что узнал об этом. Печать 'Функция в файле ab'.
  • Конец файла; назад к "__main__"!
  • О, функция. Я это запомню.
  • Другой.
  • Функция x(); хорошо, напечатайте «периферийная задача: может быть полезно в других проектах».
  • Что это? Заявление if. Что ж, условие выполнено (для переменной __name__ установлено значение "__main__"), поэтому я ввожу функцию main() и печатаю «основная функция: здесь действие».

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

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

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

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

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

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

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

При разделении независимых функций вы получаете возможность повторно использовать свою предыдущую работу, вызывая их в другой скрипт. Например, «example.py» может импортировать «xy.py» и вызывать x(), используя функцию «x» из «xy.py». (Возможно, это использование заглавной буквы третьего слова данной текстовой строки; создание массива NumPy из списка чисел и их возведение в квадрат; или устранение тренда трехмерной поверхности. Возможности безграничны.)

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

person joechoj    schedule 29.09.2016

Когда в нашем модуле (M.py) есть определенные операторы, которые мы хотим выполнить, когда он будет работать как основной (не импортированный), мы можем поместить эти операторы (тестовые примеры, операторы печати) в этот блок if.

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

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

person Nabeel Ahmed    schedule 03.04.2013

Проще говоря, __name__ - это переменная, определенная для каждого сценария, которая определяет, запускается ли сценарий как основной модуль или как импортированный модуль.

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

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

а также

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

Результат выполнения script1:

Script 1's name: __main__

Результат выполнения script2:

Script1's name is script1
Script 2's name: __main__

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

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

«Сложный

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

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

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

person redbandit    schedule 15.10.2016
comment
Иллюстрация C / C ++ неверна: 3 раза одно и то же имя модуля (file1). - person Wolf; 11.01.2018

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

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

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

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

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

person Alisa    schedule 20.01.2015
comment
Мне не удалось отредактировать сообщение (минимум 6 символов, если требуется изменение). В строке 14 написано «x.y», а не «x.py». - person fpsdkfsdkmsdfsdfm; 06.05.2020

Я так много читал ответы на этой странице. Я бы сказал, что если вы знаете эту вещь, вы наверняка поймете эти ответы, в противном случае вы все равно запутаетесь.

Короче, нужно знать несколько моментов:

  1. import a действие фактически запускает все, что может быть запущено в a.py, то есть каждая строка в a.py

  2. Из-за пункта 1 вы можете не захотеть, чтобы все запускалось в a.py при импорте.

  3. Чтобы решить проблему в пункте 2, python позволяет поставить проверку состояния

  4. __name__ - неявная переменная во всех .py модулях:

  • когда a.py imported, значение __name__ модуля a.py устанавливается равным имени его файла a
  • когда a.py запускается напрямую с использованием python a.py, значение __name__ устанавливается в строку __main__
  1. Знаете ли вы, как достичь точки 3, основываясь на механизме того, как python устанавливает переменную __name__ для каждого модуля? Ответ довольно прост, правда? Поместите условие if: if __name__ == "__main__": // do A
  • тогда python a.py запустит часть // do A
  • и import a пропустит часть // do A
  1. Вы даже можете поставить if __name__ == "a" в зависимости от ваших функциональных потребностей, но редко

Важным моментом в том, что Python является особенным, является пункт 4! Остальное - всего лишь базовая логика.

person jack    schedule 24.06.2018
comment
Да, пункт 1 жизненно важен для понимания. Отсюда становится понятна необходимость в этом механизме. - person Eureka; 25.03.2019
comment
Пригвоздил, все еще был полностью сбит с толку приведенными выше ответами, но теперь это кристально ясно! - person bad_coder; 31.01.2021
comment
это должен быть принятый ответ .. - person Sunil Garg; 16.02.2021

Когда вы запускаете 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.
person Zain    schedule 11.12.2013

Рассмотреть возможность:

if __name__ == "__main__":
    main()

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

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

person Larry    schedule 22.08.2017

Прежде чем что-либо объяснять о if __name__ == '__main__', важно понять, что такое __name__ и для чего он нужен.

Что такое __name__?

__name__ - это DunderAlias ​​ - может рассматриваться как глобальная переменная (доступная из модулей) и работает в аналогичный способ global.

Это строка (глобальная, как упомянуто выше), обозначенная type(__name__) (дающая <class 'str'>), и является встроенным стандартом для версии Python 3 и Python 2.

Где:

Его можно не только использовать в сценариях, но также можно найти как в интерпретаторе, так и в модулях / пакетах.

Переводчик:

>>> print(__name__)
__main__
>>>

Скрипт:

test_file.py:

print(__name__)

Результат в __main__

Модуль или пакет:

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

Результатом somefile

Обратите внимание, что при использовании в пакете или модуле __name__ принимает имя файла. Путь к фактическому модулю или пакету не указан, но есть собственный DunderAlias ​​__file__, который позволяет это.

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

Практика:

Переменная означает, что ее значение может быть перезаписано («можно» не означает «следует»), перезапись значения __name__ приведет к ухудшению читаемости. Так что не делайте этого ни по какой причине. Если вам нужна переменная, определите новую переменную.

Всегда предполагается, что значение __name__ равно __main__ или имени файла. Еще раз изменение этого значения по умолчанию вызовет еще большую путаницу, что это принесет пользу, что вызовет проблемы в дальнейшем.

пример:

>>> __name__ = 'Horrify' # Change default from __main__
>>> if __name__ == 'Horrify': print(__name__)
...
>>> else: print('Not Horrify')
...
Horrify
>>>

В целом считается хорошей практикой включать if __name__ == '__main__' в сценарии.

Теперь к ответу if __name__ == '__main__':

Теперь мы знаем, что поведение __name__ вещей стало яснее:

if - это оператор управления потоком, содержащий блок кода. будет выполняться, если заданное значение истинно. Мы видели, что __name__ может принимать либо __main__, либо имя файла, из которого он был импортирован.

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

Если действительно __name__ принимает значение __main__, то все, что находится в этом блоке кода, будет выполнено.

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

Модули:

__name__ также может использоваться в модулях для определения имени модуля.

Варианты:

С __name__ также можно делать другие, менее распространенные, но полезные вещи, некоторые из которых я покажу здесь:

Выполняется, только если файл является модулем или пакетом:

if __name__ != '__main__':
    # Do some useful things 

Выполнение одного условия, если файл является основным, и другого, если это не так:

if __name__ == '__main__':
    # Execute something
else:
    # Do some useful things

Вы также можете использовать его для предоставления работоспособных справочных функций / утилит по пакетам и модулям без сложного использования библиотек.

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

person Simon    schedule 03.04.2018

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

В качестве примера рассмотрим следующий модуль my_test_module.py:

# my_test_module.py

print('This is going to be printed out, no matter what')

if __name__ == '__main__':
    print('This is going to be printed out, only if user invokes the module as a script')

1-й вариант: импортировать my_test_module.py в другой модуль

# main.py

import my_test_module

if __name__ == '__main__':
    print('Hello from main.py')

Теперь, если вы вызовете main.py:

python main.py 

>> 'This is going to be printed out, no matter what'
>> 'Hello from main.py'

Обратите внимание, что выполняется только оператор print() верхнего уровня в my_test_module.


2-й вариант: вызвать my_test_module.py как сценарий

Теперь, если вы запустите my_test_module.py как сценарий Python, оба оператора print() будут выполнены:

python my_test_module.py

>>> 'This is going to be printed out, no matter what'
>>> 'This is going to be printed out, only if user invokes the module as a script'

Для более полного объяснения вы можете прочитать Что делает if __name__ == '__main__' в Python .

person Giorgos Myrianthous    schedule 01.02.2020

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

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

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

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

person Inconnu    schedule 30.11.2016

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

Это можно было записать несколькими способами. Другой:

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

Я не говорю, что вы должны использовать это в производственном коде, но это служит иллюстрацией того, что в if __name__ == '__main__' нет ничего волшебного.

Это просто соглашение для вызова основной функции в файлах Python.

person Prof. Falken    schedule 24.01.2013
comment
Я считаю это дурным тоном, поскольку вы 1) полагаетесь на побочные эффекты и 2) злоупотребляете and. and используется для проверки истинности двух логических операторов. Поскольку вас не интересует результат and, выражение if более четко передает ваши намерения. - person jpmc26; 26.12.2013
comment
Оставляя в стороне вопрос о том, является ли использование короткого замыкания логических операторов в качестве механизма управления потоком плохим стилем или нет, более серьезная проблема заключается в том, что этот вообще не отвечает на этот вопрос. - person Mark Amery; 10.07.2015
comment
@ jpmc26 Любой человек, имеющий опыт работы с Perl или Javascript, полностью доволен этой идиомой, используя and в качестве управляющего оператора. У меня нет никаких проблем с этим. Другая похожая идиома использует or для установки значений по умолчанию. Например, x = input("what is your name? ") or "Nameless Person". - person John Henckel; 09.07.2021
comment
@JohnHenckel Это не Perl или JavaScript. Это не идиома Python. Использование функции с побочными эффектами в середине логического оператора в Python считается дурным тоном. В частности, в этом случае нет никакой пользы от использования and здесь; функция даже не возвращает значение. Это просто делает код менее очевидным. - person jpmc26; 09.07.2021
comment
@ jpmc26 Я пытаюсь найти авторитетный источник, который согласен с вами. Это где-то упоминается? Например, в PEP8 говорится, что нам следует избегать использования and для целей управления или использования or для присвоения значения по умолчанию? Пытался погуглить, но ничего не нашел. - person John Henckel; 20.07.2021
comment
@JohnHenckel См. PEP 20. Явный лучше, чем неявный, удобочитаемость важна, и должен быть один - и желательно только один - очевидный способ сделать это. Вам не нужно, чтобы кто-то говорил, чтобы не скрывать вызов в операторе and. В Python есть конструкции, которые делают такое поведение более очевидным для читателя. Шаблон использования здесь (выполните следующий код, если условие истинно) - это единственная цель, для которой был разработан if; and был разработан, чтобы вычислить, выполняются ли одновременно два условия. Второй операнд этого оператора and даже не используется. - person jpmc26; 21.07.2021

Система (интерпретатор 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» в этом конкретном экземпляре.

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

person codewizard    schedule 25.11.2015

if __name__ == "__main__": - это в основном среда сценариев верхнего уровня, и она определяет интерпретатор, который («У меня самый высокий приоритет, который должен быть выполнен первым»).

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

if __name__ == "__main__":
    # Execute only if run as a script
    main()
person The Gr8 Adakron    schedule 24.04.2016

Рассмотреть возможность:

print __name__

Результатом выше является __main__.

if __name__ == "__main__":
  print "direct method"

Вышеупомянутое утверждение верно и выводит "прямой метод". Предположим, что если они импортировали этот класс в другой класс, он не печатает «прямой метод», потому что при импорте он установит __name__ equal to "first model name".

person Janarthanan Ramu    schedule 22.06.2016

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

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

person kgf3JfUtW    schedule 13.03.2017

Причина для

if __name__ == "__main__":
    main()

в первую очередь, чтобы избежать проблем блокировки импорта, которые возникнет из-за прямого импорта кода. Вы хотите, чтобы main() запускался, если ваш файл был вызван напрямую (это __name__ == "__main__" случай), но если ваш код был импортирован, то импортер должен ввести ваш код из истинного основного модуля, чтобы избежать проблем с блокировкой импорта.

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

person personal_cloud    schedule 22.09.2017
comment
Приятно узнать о блокировке импорта. Не могли бы вы объяснить, как подписаться на методологию, которая [...] немного больше? - person Wolf; 11.01.2018
comment
@Wolf: Конечно. Я добавил несколько предложений о методологии множественных точек входа. - person personal_cloud; 14.04.2018

Каждый модуль в Python имеет атрибут __name__. Значение атрибута __name__ равно __main__, когда модуль запускается напрямую, например python my_module.py. В противном случае (например, когда вы говорите import my_module) значение __name__ - это имя модуля.

Небольшой пример для краткого объяснения.

#Script test.py

apple = 42

def hello_world():
    print("I am inside hello_world")

if __name__ == "__main__":
    print("Value of __name__ is: ", __name__)
    print("Going to call hello_world")
    hello_world()

Мы можем выполнить это напрямую как

python test.py  

Выход

Value of __name__ is: __main__
Going to call hello_world
I am inside hello_world

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

#script external_calling.py

import test
print(test.apple)
test.hello_world()

print(test.__name__)

Когда вы выполняете это

python external_calling.py

Выход

42
I am inside hello_world
test

Таким образом, выше самоочевидно, что когда вы вызываете тест из другого скрипта, цикл if __name__ в test.py не будет выполняться.

person Rishi Bansal    schedule 12.06.2019

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

  1. Вызов класса из других файлов. Вам просто нужно импортировать его в вызывающую программу.

  2. Запустите класс отдельно в целях тестирования.

В последнем случае класс должен содержать общедоступный статический метод void main (). В Python этой цели служит глобально определенный ярлык '__main__'.

person Raja    schedule 07.10.2018

Если этот файл .py импортируется другими файлами .py, код под «оператором if» не будет выполнен.

Если этот .py запускается python this_py.py под оболочкой или дважды щелкнул в Windows. код под «оператором if» будет выполнен.

Обычно пишется для тестирования.

person pah8J    schedule 19.06.2018

Если интерпретатор python запускает конкретный модуль, глобальная переменная __name__ будет иметь значение "__main__".

  def a():
      print("a")
  def b():
      print("b")

  if __name__ == "__main__": 

          print ("you can see me" )
          a()
  else: 

          print ("You can't see me")
          b()

При запуске этот скрипт печатает вы можете видеть меня

а

Если вы импортируете этот файл, скажем, A в файл B и выполните файл B, тогда if __name__ == "__main__" в файле A станет false, поэтому он напечатает Вы меня не видите.

б

person Nikil Munireddy    schedule 30.07.2019

если name == 'main':

Мы видим, если __name__ == '__main__': довольно часто.

Он проверяет, импортируется модуль или нет.

Другими словами, код в блоке if будет выполняться только тогда, когда код запускается напрямую. Здесь directly означает not imported.

Давайте посмотрим, что он делает, используя простой код, который печатает имя модуля:

# test.py
def test():
   print('test module name=%s' %(__name__))

if __name__ == '__main__':
   print('call test()')
   test()

Если мы запустим код напрямую через python test.py, имя модуля будет __main__:

call test()
test module name=__main__
person Ali Hallaji    schedule 04.04.2018

Простыми словами:

Код, который вы видите в if __name__ == "__main__":, будет вызван только тогда, когда ваш файл python выполняется как python example1.py.

Однако, если вы хотите импортировать свой файл python example1.py в качестве модуля для работы с другим файлом python, скажем, example2.py, код под if __name__ == "__main__": не будет запущен и не будет действовать.

person Mustapha Babatunde    schedule 22.10.2020

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

Предположим, у вас есть два файла Python, a.py и b.py. Теперь a.py импортирует b.py. Мы запускаем файл a.py, где сначала выполняется код «import b.py». Перед запуском остальной части кода a.py необходимо полностью выполнить код в файле b.py.

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

Вот что проверяет эта строка кода. Если это основной файл (например, b.py), выполняющий код, а в данном случае это не так (a.py - это основной запущенный файл), то выполняется только код.

person preetika mondal    schedule 04.05.2018

Создайте файл a.py:

print(__name__) # It will print out __main__

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

Создайте еще один файл b.py в том же каталоге:

import a  # Prints a

Запустить его. Он напечатает a, то есть имя файла, который импортируется.

Итак, чтобы показать два разных поведения одного и того же файла, обычно используется следующий трюк:

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly
person DARK_C0D3R    schedule 08.01.2018

Каждый модуль в Python имеет специальный атрибут под названием name. Значение атрибута name устанавливается на «main», когда модуль выполняется как основная программа (например, выполняется python foo.py). В противном случае значение name устанавливается равным имени модуля, из которого он был вызван.

person Reinstate C0MMUNiSM    schedule 27.04.2020

Когда файл python выполняется, он создает много специальных переменных, таких как __name__. Переменная __name__ содержит имя файла. и ответ на ваш вопрос таков:

if __name__ == "__main__":
       #do something

Это означает, что если имя исполняемого файла выполняется как исходный файл, а НЕ МОДУЛЬ, тогда код внутри него запускается, это можно доказать на простом примере. Создайте два файла Python foo.py и second.py, затем в foo.py введите это

if __name__ == "__main__":
       print("file is not imported")
else:
       print("file is imported")

и в second.py введите это

import foo

if foo.__name__ == "__main__":
       print("file is not imported")
else:
       print("file is imported")

в дополнение к этому, если вы сделаете это print(__name__), тогда он напечатает __main__ почему? потому что файл работает как основной источник, и если вы сделаете print(foo.__name__), он напечатает foo, потому что значение переменной __name__ по умолчанию - это имя файла, и по умолчанию я имею в виду, что вы тоже можете его изменить для этого просто перейдите в foo.py и сделайте это __name__ = "name", а затем, когда вы запустите файл, например

__name__ = "hello world"
print(__name__)

тогда вывод будет

hello world
person PYC    schedule 09.04.2021

ОСНОВНАЯ ФУНКЦИЯ PYTHON - отправная точка любой программы. Когда программа запускается, интерпретатор python запускает код последовательно. Основная функция выполняется только тогда, когда она запускается как программа Python ...

def main():
     print ("i am in the function")
print ("i am out of function")

при запуске скрипта show:

i am out of function

а не код "я в функции" Это потому, что мы не объявили функцию вызова "if__name __ ==" main ". если вы используете from it:

def main():
     print ("i am in the function")


if __name__ == "__main__":
    main()

print ("i am out of function")

Выход равен

i am in the function
i am out of function

В Python "if__name __ ==" main "позволяет запускать файлы Python либо как повторно используемые модули, либо как автономные программы.

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

Когда вы выполняете основную функцию, она затем считывает оператор «if» и проверяет, совпадает ли name с main.

В Python "if__name __ ==" main "позволяет запускать файлы Python либо как повторно используемые модули, либо как автономные программы.

person mamal    schedule 21.04.2020

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

person Mohammed Awney    schedule 03.02.2019
comment
В этом ответе предполагается, что OP (или любой пользователь с аналогичным вопросом) знаком с C и знает, что такое точка входа. - person arredond; 22.02.2019
comment
В этом ответе также предполагается, что перед блоком if __name__ == "__main__" не используется код (кроме определений без побочных эффектов). Технически вершина исполняемого скрипта является точкой входа в программу. - person Charlie Harding; 10.04.2019

if __name__ = "__main__" означает, что если вы обычно запускаете файл python, например python foo.py, он назначит специальную переменную __name__ "__main__", но если вы импортируете файл, например import foo, он назначит __name__ "foo" и не запустит функцию.

person B R U H    schedule 09.02.2021

Я новичок в Python, но хотел бы написать здесь.

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

Ну, я импортирую их, но в конце этого файла помещаю __ name __ = '__ main __'

Когда мы импортируем модуль, весь код внутри него выполняется от начала до конца, но когда он достигает условия, он не запускает func, fucn2 и ..., что является очисткой Википедии.

Ну, в глобальной области Python __ name __ определен как '__ main __' для текущей программы

Когда мы импортируем модуль, он определяется как переменная в пространстве имен нашей текущей программы, а текущая программа __ name __ - '__ main __'

#test.py
def func():
    #do somthing
    pass
def func2():
    #do somthing
    pass
print('The program name is set to',globals()['__name__'])

if __name__=='__main__':
    #in current program __name__ is equal '__main__' 
    func('https://www.wikipedia.org')
    func2('https://www.wikipedia.org')
    #or do more job
    
import test1
print('inside of current program')
print('name is current program',__name__)
print(globals()['test1'])
test1.func('another site')
test1.func2('another site')

выход

inside of test 1
name of program is set to  test1
end of madule
inside of current
__main__
<module 'test1' from 'C:\\users\\ir\\appdata\\local\\programs\\python\\python38\\lib\\test1.py'>
person Warrior199    schedule 04.07.2021

Вы можете проверить специальную переменную __name__ с помощью этого простого примера:

создать file1.py

if __name__ == "__main__":
    print("file1 is being run directly")
else:
    print("file1 is being imported")

создать file2.py

import file1 as f1

print("__name__ from file1: {}".format(f1.__name__))
print("__name__ from file2: {}".format(__name__))

if __name__ == "__main__":
    print("file2 is being run directly")
else:
    print("file2 is being imported")

Выполнить file2.py

вывод:

file1 is being imported
__name__ from file1: file1
__name__ from file2: __main__
file2 is being run directly
person Igor Micev    schedule 31.01.2020

когда вы выполняете модуль (исходный файл), if-condition проверяет, вызывается ли модуль напрямую или из другого исходного файла. здесь прямо имеется ввиду не импортированный.

если он вызывается напрямую для выполнения, имя модуля устанавливается как main, а затем выполняется код в блоке if.

person Sindhukumari P    schedule 05.05.2021