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

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

# Threading example
import time, thread

def myfunction(string, sleeptime, lock, *args):
    while True:
        lock.acquire()
        time.sleep(sleeptime)
        lock.release()
        time.sleep(sleeptime)

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

53 ответа

Решение

Всякий раз, когда интерпретатор 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("before __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__ Переменная (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 и запускается.

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

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

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

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

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


Почему нам это надо?

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

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

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

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

do_important()

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

~$ python important.py

Эта проблема

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

import important

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

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

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

Лучший путь

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

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

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

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

if __name__ == "__main__":
    do_important()

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

Еще лучший путь

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

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

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

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

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

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

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

import important
important.main()

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

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

if __name__ == '__main__':
    main()

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, Оператор import запускает модуль сразу после импорта, поэтому ab операции выполняются до конца xy "S. После того, как закончил с 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() function and print ' main function: это где действие '.

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

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

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

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

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

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

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

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

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

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

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

# my_test_module.py

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

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

1-я возможность: Импорт my_test_module.py в другом модуле

# main.py

import my_test_module

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

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

python main.py 

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

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


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

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

python my_test_module.py

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

__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) предоставляет для исходных файлов (модулей). Вы можете получить их значения в любое время, поэтому давайте сосредоточимся на переменной / атрибуте __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" в данном конкретном случае.

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

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

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

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

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

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

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

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

print __name__

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

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

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

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

Чуть более подробно, скажем, у вас есть простой скрипт fib.py(адаптировано из этого ответа ):

      # XXX FIXME: useless (see below)
if __name__ == "__main__":
    n = int(input('Write a number: '))
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    print('Fibonacci number %i: %i' % (n, b))

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

      n = int(input('Write a number: '))
a, b = 0, 1
while b < n:
    a, b = b, a+b
print('Fibonacci number %i: %i' % (n, b))

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

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

      def main():
    n = int(input('Write a number: '))
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    print('Fibonacci number %i: %i' % (n, b))

if __name__ == "__main__":
    main()

Теперь, если ты import fib, призыв к main()не будет выполнен; но когда ты бежишь python fib.py, Так и будет.

На самом деле, лучшим дизайном все же было бы изолировать многоразовую часть (фактическое вычисление) от видимого пользователем ввода / вывода:

      def fibn(n: int) -> int:
    a, b = 0, 1
    while b < n:
        a, b = b, a+b
    return b

def main():
    n = int(input('Write a number: '))
    print('Fibonacci number %i: %i' % (n, fibn(n)))

if __name__ == "__main__":
    main()

Теперь вы можете from fib import fibn и вызовите функцию из кода, который это выполняет.

(Я назвал функцию fibn()просто чтобы было понятнее, что к чему в этом примере. В реальной жизни это можно назвать fib() и делать from fib import fib.)

Точно так же вы могли бы import и вызовите функцию, если хотите использовать ее повторно.

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

      def main():
    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()

Это меняет объем lockПеременная; если окружающему коду требуется доступ к нему, вам нужно будет сделать его global (или, может быть, лучше, рефакторинг main к return lock, и пусть вызывающий объект фиксирует значение в собственной локальной переменной).

Причина для

if __name__ == "__main__":
    main()

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

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

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

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

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

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

#Script test.py

apple = 42

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

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

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

python test.py  

Выход

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

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

#script external_calling.py

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

print(test.__name__)

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

python external_calling.py

Выход

42
I am inside hello_world
test

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

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

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

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

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

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

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

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

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

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

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

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

  if __name__ == "__main__": 

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

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

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

а

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

б

если 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__
Другие вопросы по тегам