Вопрос

Что это 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))
Это было полезно?

Решение

Всякий раз, когда интерпретатор 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")

Другие советы

Когда ваш скрипт запускается путем передачи его в качестве команды интерпретатору 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 __ " .

Самое простое объяснение __name__ переменная (имхо) следующая:

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

# 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 и ведется.

Что это 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, т.е.чтения, оценки, цикла печати или REPL интерпретатора), вы запускаете все из его "__main__".

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

if __name__ == "__main__":
    do_important()

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

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

Однако есть питонический способ улучшить это.

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

Если мы поместим код, который хотим использовать при разработке и тестировании, в такую ​​функцию, а затем выполним проверку на наличие '__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()

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

Что значит 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()

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

Возьмем файл «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 из списка чисел и возведение их в квадрат;или удаление тренда на 3D-поверхности.Возможности безграничны.)

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

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

Как по умолчанию (когда модуль работает как основной, а не импортированный), переменная __name __ имеет значение " __ main __ " , и когда она будет импортирована, < Переменная code> __name __ получит другое значение, скорее всего, имя модуля ( 'M' ). Это полезно при запуске различных вариантов модулей и разделении их конкретного входа & amp; выходные операторы, а также, если есть какие-либо тесты.

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

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

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

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

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

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

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

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

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

и

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

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

Script 1's name: __main__

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

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

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

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

Complicated importing in C

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

Elegant importing in Python

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

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

Учитывать:

if __name__ == "__main__":
    main()

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

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

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

Что __name__?

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

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

Где:

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

Устный переводчик:

>>> print(__name__)
__main__
>>>

Скрипт:

test_file.py:

print(__name__)

В результате чего __main__

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

какой-тофайл.py:

def somefunction():
    print(__name__)

тестовый_файл.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

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

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

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

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

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

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

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

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

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

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

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

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

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

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

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

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

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

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

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

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

'__ main __' - это имя области, в которой выполняется код верхнего уровня. Модуль & # 8217; s __name __ устанавливается равным '__ main __' при чтении из стандартного ввода, сценария или из интерактивного приглашения.

if __name__ == "__main__":
    # Execute only if run as a script
    main()

Причина

if __name__ == "__main__":
    main()

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

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

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

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

<Ол>
  • import a фактически выполняет все, что можно запустить в " a "

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

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

  • __name __ является неявной переменной во всех модулях .py; когда импортируется a.py, значение __name __ модуля a.py устанавливается равным его имени файла " a " ;; когда a.py запускается напрямую с использованием «python a.py», что означает, что a.py является точкой входа, тогда значение __name __ модуля a.py устанавливается в строку __ __ Основной

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

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

    Учитывать:

    print __name__
    

    Вывод для вышеизложенного: __main__.

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

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

      

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

    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

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

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

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

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

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

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

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

    Создайте файл, 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
    

    if name == ' main ':

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

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

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

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

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

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

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

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

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

    Небольшой пример, чтобы объяснить вкратце.

    #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 имя в test.py не будет выполняться.

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top