28 Вопрос: Что делать, если __name__ == «__main__»: делать?

вопрос создан в Fri, May 25, 2018 12:00 AM

Что делает 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))
    
5111
28 ответов                              28                         

Всякий раз, когда интерпретатор 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, уберет .py и присвоит эту строку переменной вашего модуля __name__, т.е.

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

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.

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")
    
5471
2019-06-24 03: 21: 09Z
  1. Из любопытства: что произойдет, если я запущу subprocess.run('foo_bar.py') в скрипте Python? Я полагаю, что foo_bar будет запущен с __name__ = '__main__' так же, как когда я вручную вводю foo_bar.py в cmd. Это тот случай? Принимая во внимание @MrFooz 'Answer, не должно быть никаких проблем с этим и наличием столько «основных» модулей одновременно, сколько мне нравится. Даже изменение значения __name__ или наличие нескольких независимых экземпляров (или экземпляров, которые создали друг друга с помощью subprocess), взаимодействующих друг с другом, должно быть обычным делом для Python. Я что-то пропустил?
    2019-02-18 16: 09: 14Z
  2. @ hajef Вы правы относительно того, как все будет работать с subprocess.run. Тем не менее, как правило, лучший способ совместного использования кода между сценариями - это создание модулей, в которых сценарии вызывают общие модули вместо вызова друг друга в качестве сценариев. Трудно отлаживать вызовы subprocess.run, так как большинство отладчиков не пересекают границы процессов, это может добавить нетривиальные издержки системы для создания и уничтожения дополнительных процессов и т. Д.
    2019-02-19 16: 16: 03Z
  3. У меня есть сомнения в примере foo2.py в разделе «пища для размышлений». Что делает функция импорта из foo2.pyB? На мой взгляд, он просто импортирует foo2.py из functionB
    2019-02-24 13: 47: 03Z
  4. @ MrFooz Я никогда не собирался делать что-то подобное этому xD Это просто пришло мне в голову, и я понял, что это странно, возможно, помочь ppl. обдумывая подобные вещи. @ user471651 Почему from foo2 import functionB должен импортировать foo2 из функции B? Это семантическое искажение. from module import method импортирует метод из модуля.
    2019-02-25 15: 51: 16Z
  5. ты бог питона? приятное объяснение: D
    2019-06-18 03:20: 56Z

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

 
python myscript.py

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

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

 
if __name__ == "__main__":
    ...

Если ваш скрипт импортируется в другой модуль, его различные функции и определения классов будут импортированы, а его код верхнего уровня будет выполнен, но код в тогдашнем теле предложения 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__".

    
1640
2018-01-31 13: 28: 16Z

ПростыеОбъяснение для переменной __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 и выполняется.

    
653
2018-12-18 09: 25: 19Z
  

Что делает 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, то есть чтения, 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()
    
470
2018-03-27 02: 27: 47Z

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

    
110
2015-07-10 15: 49: 13Z
  

Что делает 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()
    
71
2017-01-10 17: 35: 04Z

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

Взять файл "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. Оператор import сразу же запускает модуль при импорте, поэтому операции 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 function: здесь действие ».

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

  

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

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

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

  

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

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

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

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

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

    
62
2018-05-23 22: 29: 32Z

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

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

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

    
45
2018-05-23 22: 07: 29Z

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

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

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

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

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

    
35
2015-03-04 20: 31: 20Z

Проще говоря, __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 ++, где, если файл не реализует функцию main, он не может быть скомпилирован как исполняемый файл, и если он это делает, затем его нельзя использовать в качестве библиотеки.

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

 Compliимпортированный в C

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

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

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

    
35
2018-05-23 22: 28: 19Z
  1. Иллюстрация C /C ++ неверна: 3 раза одно и то же имя модуля ( file1 ).
    2018-01-11 12: 59: 53Z

Когда вы запускаете 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.
    
32
2013-12-11 11: 23: 53Z

Рассмотрим:

 
if __name__ == "__main__":
    main()

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

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

    
29
2018-05-23 22: 31: 42Z

Прежде чем что-то объяснять о 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 является оператором управления потоком, который содержит Блок кода будет выполняться, если задано значение true. Мы видели, что __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

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

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

    
25
2018-05-23 22: 39: 09Z

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

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

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

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

    
22
2018-05-23 22: 30: 36Z

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

Это может быть написано несколькими способами. Еще один:

 
def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

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

    
20
2018-09-03 07: 05: 11Z
  1. Я бы посчитал эту плохую форму, поскольку вы 1) полагаетесь на побочные эффекты и 2) злоупотребляете and. and используется для проверки, являются ли два логических оператора истинными. Поскольку вас не интересует результат and, утверждение if более четко отражает ваши намерения.
    2013-12-26 18: 07: 26Z
  2. Оставляя в стороне вопрос о том, является ли использование поведения булевых операторов при коротком замыкании в качестве механизма управления потоком плохим стилем или нет, большая проблема заключается в том, что это не не отвечай на вопрос вообще .
    2015-07-10 15: 33: 06Z

Существует ряд переменных, которые система (интерпретатор 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 » в данном конкретном случае.

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

    
19
2016-07-20 09: 30: 24Z

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

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

 
if __name__ == "__main__":
    # Execute only if run as a script
    main()
    
16
2018-05-23 22: 14: 07Z

Причина

 
if __name__ == "__main__":
    main()

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

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

    
14
2018-04-18 21: 05: 59Z
  1. Полезно узнать о блокировке импорта . Не могли бы вы объяснить вход в методологию, которая [...] будет немного больше?
    2018-01-11 13: 06: 38Z
  2. @ Wolf: Конечно. Я добавил несколько предложений о методологии множественных точек входа.
    2018-04-14 00: 26: 20Z

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

Чтобы быть кратким, вам нужно знать несколько моментов:

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

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

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

  4. __name__ - неявная переменная во всех модулях .py; когда импортируется a.py, значение __name__ модуля a.py устанавливается на его имя файла «a»; когда a.py запускается напрямую с использованием «python a.py», что означает, что a.py является точкой входа, тогда значение __name__ модуля a.py устанавливается в строку __main__

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

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

    
13
2018-06-24 15: 48: 36Z
  1. Да, пункт 1 крайне важен для понимания. Из этого становится очевидной необходимость этого механизма.
    2019-03-24 21: 16: 18Z

Рассмотрим:

 
print __name__

Выход для вышеупомянутого __main__.

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

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

    
13
2019-02-06 23: 16: 06Z
  

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

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 р>     

12
2017-03-13 21: 44: 26Z

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

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

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

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

    
8
2018-10-18 03: 09: 32Z

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

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

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

    
5
2018-06-19 11: 44: 29Z

Создайте файл, 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
    
4
2018-05-23 22: 34: 14Z

if 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__
    
3
2018-05-23 22: 36: 51Z

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

Предположим, у вас есть два файла 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 - основной файл, на котором выполняется), то выполняется только код.

    
3
2018-05-23 22: 38: 56Z

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

    
2
2019-02-06 23: 13: 57Z
  1. Этот ответ предполагает, что OP (или любой пользователь с похожим вопросом) знакомы с C и я> знаю, что такое точка входа.
    2019-02-22 12: 44: 37Z
  2. В этом ответе также предполагается, что перед блоком if __name__ == "__main__" отсутствует код (кроме определений без побочных эффектов). Технически вершина исполняемого скрипта является точкой входа в программу.
    2019-04-09 21: 35: 39Z

Каждый модуль в python имеет атрибут, который называется name . Атрибут name имеет значение main , когда модуль запускается напрямую. В противном случае значение 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

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

    
1
2019-06-12 09: 28: 39Z
источник размещен Вот