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


6070

Учитывая следующий код, что делает 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))

if __name__ == "__main__":Является ли состояние блока устаревшим или устаревшим по сравнению с Python 3? Я нашел некоторую информацию, подтверждающую это.
carloswm85

2
@ carloswm85 Это не правда.
Гиоргос Мириантос

Ответы:


6653

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

14
Из любопытства: что произойдет, если я запустлю subprocess.run('foo_bar.py')скрипт на python? Я полагаю, что foo_barэто будет начинаться так __name__ = '__main__'же, как при foo_bar.pyручном вводе cmd. Это тот случай? Принимая во внимание @MrFooz 'Answer, не должно быть никаких проблем с этим и наличием столько «основных» модулей одновременно, сколько мне нравится. Даже изменение __name__значения или наличие нескольких независимых созданий экземпляров (или экземпляров, которые создали друг друга subprocess), взаимодействующих друг с другом, должно быть обычным делом для Python. Я что-то пропустил?
Хажеф

12
@hajef Ты прав насчет того, как все будет работать subprocess.run. Тем не менее, как правило, лучший способ совместного использования кода между сценариями - это создание модулей, в которых сценарии вызывают общие модули вместо вызова друг друга в качестве сценариев. Трудно отлаживать subprocess.runвызовы, так как большинство отладчиков не пересекают границы процессов, они могут добавить нетривиальные издержки системы для создания и уничтожения дополнительных процессов и т. Д.
г-н Фуз

4
У меня есть сомнения в примере foo2.py в разделе «Пища для размышлений». Что делает функция импорта из foo2.pyB? На мой взгляд, он просто импортирует foo2.py из функции
B

1
@MrFooz Я никогда не собирался делать что-то вроде этого xD. Это просто пришло мне в голову, и я понял, что это странно - помочь людям. обдумывая подобные вещи. @ user471651 Зачем from foo2 import functionBимпортировать foo2 из функции B ? Это семантическое искажение. from module import methodимпортирует метод из модуля.
Хажеф

2
Один из модулей, который может импортировать ваш код multiprocessing, в частности, делает этот тест необходимым в Windows.
Ян Вернье

1801

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

python myscript.py

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

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

if __name__ == "__main__":
    ...

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

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

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

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")
# file two.py
import one

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

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

Теперь, если вы вызываете переводчик как

python one.py

Выход будет

top-level in one.py
one.py is being run directly

Если вы запустите two.pyвместо:

python two.py

Ты получаешь

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

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


Удивительный ответ, это был самый ясный ответ на мой взгляд. +1!
TheTechRobo36414519

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

719

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


513

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

125

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


2
Почему файл helloworld.pyс только что print("hello world")в нем может работать с командой, python helloworld.pyдаже если нет if __name__ == "__main__"?
привет, 15

83

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

72

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


52

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

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

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


43

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


2
Иллюстрация C / C ++ неверна: 3 раза одно и то же имя устройства ( file1 ).
Вольф

40

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

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

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

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

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


1
Я не смог отредактировать сообщение (минимум 6 символов, если требуется изменение). Строка 14 имеет «xy», а не «x.py».
всегда

35

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

34

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

if __name__ == "__main__":
    main()

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

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


кажется, это было слишком долго, чтобы написать яркий ответ +1
snr

27

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

Что такое __name__?

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

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

Куда:

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

Переводчик:

>>> print(__name__)
__main__
>>>

Автор сценария:

test_file.py :

print(__name__)

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

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

somefile.py:

def somefunction():
    print(__name__)

test_file.py:

import somefile
somefile.somefunction()

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

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

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

Практика:

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

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

пример:

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

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

Теперь, чтобы ответить if __name__ == '__main__':

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

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

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

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

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

Модули:

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

Варианты:

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

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

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

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

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

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

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


25

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

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

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

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


23

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

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

def some_function_for_instance_main():
    dosomething()


__name__ == '__main__' and some_function_for_instance_main()

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


7
Я бы посчитал это плохим тоном, так как вы 1) полагаетесь на побочные эффекты и 2) злоупотребляете and. andиспользуется для проверки, являются ли два логических оператора истинными. Поскольку вас не интересует результат and, в ifзаявлении более четко сообщается о ваших намерениях.
jpmc26

8
Оставляя в стороне вопрос о том, является ли использование поведения булевых операторов при коротком замыкании в качестве механизма управления потоком плохим стилем или нет, большая проблема заключается в том, что это вообще не отвечает на вопрос .
Марк Амери

@MarkAmery хаха, блин, теперь так и есть. Contract
Проф. Фалькен нарушил контракт

19

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

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


17

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

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

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

17

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

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

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

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


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

16

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

print __name__

Выход для вышеизложенного есть __main__.

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

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


14

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

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


14

Причина для

if __name__ == "__main__":
    main()

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

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


3
Полезно узнать о блокировке импорта . Не могли бы вы объяснить, как подписать методологию, которая [...] будет немного больше?
Вольф

1
@ Волк: Конечно. Я добавил несколько предложений о методологии множественных точек входа.
personal_cloud

11

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

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

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

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


11

Код под 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'

10

Каждый модуль в 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

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


6

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

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

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


6

Если интерпретатор 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

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

б


5

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

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


4

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

print(__name__) # It will print out __main__

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

Создайте другой файл, b.py , в том же каталоге:

import a  # Prints a

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

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

# Code to be run when imported into another python file

if __name__ == '__main__':
    # Code to be run only when run directly

4

если 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__

4

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


8
Этот ответ предполагает, что OP (или любой пользователь с похожим вопросом) знаком с C и знает, что такое точка входа.
arredond

1
Этот ответ также предполагает, что перед if __name__ == "__main__"блоком не должно быть кода (кроме определений без побочных эффектов) . Технически вершина исполняемого скрипта является точкой входа в программу.
Чарли Хардинг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.