it-roy-ru.com

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

Что делает if __== "__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 __== "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
5082
Devoted

Всякий раз, когда интерпретатор 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 __guard")
if __== '__main__':
    functionA()
    functionB()
print("after __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.
__= "__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.
__= "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 __guard".

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

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

только когда ваш модуль импортируется другим

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

Всегда

  1. Он напечатает строку "after __guard" в обеих ситуациях.

Резюме

В итоге вот что будет напечатано в двух случаях:

# What gets printed if foo is the main program
before import
before functionA
before functionB
before __guard
Function A
Function B 10.0
after __guard
# What gets printed if foo is imported as a regular module
before import
before functionA
before functionB
before __guard
after __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 __== "__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
__= "__main__"

def bar():
    print("bar")

print("before __guard")
if __== "__main__":
    bar()
print("after __guard")
5437
Mr Fooz

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

python myscript.py

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

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

if __== "__main__":
    ...

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

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

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

if __== "__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 __== "__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__".

1639
Adam Rosenfield

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

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

# a.py
import b

а также

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

if __== '__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 и выполняется.

652
pi.

Что делает if __== "__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 __== "__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 __== '__main__':
    main()

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

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

import important
important.main()

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

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

if __== '__main__':
    main()
468
Aaron Hall

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

108
Harley Holcombe

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

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

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

python mycode.py

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

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

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

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

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

import mycode
# ... any amount of other code
mycode.main()
70
Aaron Hall

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

Возьмите файл "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 __== "__main__":
    main()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

62
joechoj

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

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

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

45
Nabeel Ahmed

Проще говоря, __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 __== "__main__":). В то время как в C/C++ вам придется разделить эти части на отдельный модуль, который затем включает файл. Изобразите ситуацию ниже;

Complicated importing in C

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

Elegant importing in Python

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

35
redbandit

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

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

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

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

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

35
Alisa

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

if __== '__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
Zain

Рассматривать:

if __== "__main__":
    main()

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

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

29
Larry

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

Пример:

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

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

Теперь ответим if __== '__main__':

Теперь мы знаем, как __name__ становится понятнее:

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

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

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

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

Модули:

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

Варианты:

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

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

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

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

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

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

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

25
Simon

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

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

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

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

21
Inconnu

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

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

def some_function_for_instance_main():
    dosomething()


__== '__main__' and some_function_for_instance_main()

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

20
Prof. Falken

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

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

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

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

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

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

if __== "__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
codewizard

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

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

if __== "__main__":
    # Execute only if run as a script
    main()
16
The Gr8 Adakron

Причина для

if __== "__main__":
    main()

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

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

14
personal_cloud

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

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

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

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

  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 __== "__main__": ...; Вы даже можете поставить, если __== "a" в зависимости от ваших функциональных потребностей

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

13
jack

Рассматривать:

print __name__

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

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

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

13
Janarthanan Ramu

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

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 __== "__main__":
    import sys
    fib(int(sys.argv[1]))

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

12
sam

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

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

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

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

7
Raja

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

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

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

5
pah8J

Создать файл 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 __== '__main__':
    # Code to be run only when run directly
4
TheVishal

if name == 'main':

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

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

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

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

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

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

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

call test()
test module name=__main__
3
Ali Hallaji

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

Предположим, что у вас есть два 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
preetika mondal

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

2
Mohammed Awney

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

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

#Script test.py

Apple = 42

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

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

Мы можем выполнить это непосредственно как

python test.py  

Результат

Value of __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 из другого скрипта, цикл loop name в test.py не будет выполнен.

1
Rishi Bansal