Вопрос: Что делать, если __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))

3983


источник


Ответы:


Когда интерпретатор Python читает исходный файл, он выполняет весь найденный в нем код.

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

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

python threading_example.py

в командной строке. После настройки специальных переменных он выполнит importи загружать эти модули. Затем он оценит defblock, создавая объект функции и создавая переменную, называемую myfunctionкоторый указывает на объект функции. Затем он прочитает ifи посмотрите, что __name__делает равным "__main__", поэтому он выполнит показанный там блок.

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

Видеть эта страница для некоторых дополнительных деталей.


4280



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


1344



Простейшее объяснение __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__']в этом модуле к имени модуля.

$ python b.py
Hello World from __main__!
Hello World again from __main__!

Как вы можете видеть, когда файл выполняется, Python устанавливает globals()['__name__']в этом файле "__main__",


541



Что это 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()

406



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


90



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

55



There are lots of different takes here on the mechanics of the code in question, the "How", but for me none of it made sense until I understood the "Why". This should be especially helpful for new programmers.

Take file "ab.py":

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

And a second file "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()

What is this code actually doing?

When you execute xy.py, you import ab. The import statement runs the module immediately on import, so ab's operations get executed before the remainder of xy's. Once finished with ab, it continues with xy.

The interpreter keeps track of which scripts are running with __name__. When you run a script - no matter what you've named it - the interpreter calls it "__main__", making it the master or 'home' script that gets returned to after running an external script.

Any other script that's called from this "__main__" script is assigned its filename as its __name__ (e.g., __name__ == "ab.py"). Hence, the line if __name__ == "__main__": is the interpreter's test to determine if it's interpreting/parsing the 'home' script that was initially executed, or if it's temporarily peeking into another (external) script. This gives the programmer flexibility to have the script behave differently if it's executed directly vs. called externally.

Let's step through the above code to understand what's happening, focusing first on the unindented lines and the order they appear in the scripts. Remember that function - or def - blocks don't do anything by themselves until they're called. What the interpreter might say if mumbled to itself:

  • Open xy.py as the 'home' file; call it "__main__" in the __name__ variable.
  • Import and open file with the __name__ == "ab.py".
  • Oh, a function. I'll remember that.
  • Ok, function a(); I just learned that. Printing 'A function in ab file'.
  • End of file; back to "__main__"!
  • Oh, a function. I'll remember that.
  • Another one.
  • Function x(); ok, printing 'peripheral task: might be useful in other projects'.
  • What's this? An if statement. Well, the condition has been met (the variable __name__ has been set to "__main__"), so I'll enter the main() function and print 'main function: this is where the action is'.

The bottom two lines mean: "If this is the "__main__" or 'home' script, execute the function called main()". That's why you'll see a def main(): block up top, which contains the main flow of the script's functionality.

Why implement this?

Remember what I said earlier about import statements? When you import a module it doesn't just 'recognize' it and wait for further instructions - it actually runs all the executable operations contained within the script. So, putting the meat of your script into the main() function effectively quarantines it, putting it in isolation so that it won't immediately run when imported by another script.

Again, there will be exceptions, but common practice is that main() doesn't usually get called externally. So you may be wondering one more thing: if we're not calling main(), why are we calling the script at all? It's because many people structure their scripts with standalone functions that are built to be run independent of the rest of the code in the file. They're then later called somewhere else in the body of the script. Which brings me to this:

But the code works without it

Yes, that's right. These separate functions can be called from an in-line script that's not contained inside a main() function. If you're accustomed (as I am, in my early learning stages of programming) to building in-line scripts that do exactly what you need, and you'll try to figure it out again if you ever need that operation again ... well, you're not used to this kind of internal structure to your code, because it's more complicated to build and it's not as intuitive to read.

But that's a script that probably can't have its functions called externally, because if it did it would immediately start calculating and assigning variables. And chances are if you're trying to re-use a function, your new script is related closely enough to the old one that there will be conflicting variables.

In splitting out independent functions, you gain the ability to re-use your previous work by calling them into another script. For example, "example.py" might import "xy.py" and call x(), making use of the 'x' function from "xy.py". (Maybe it's capitalizing the third word of a given text string; creating a NumPy array from a list of numbers and squaring them; or detrending a 3D surface. The possibilities are limitless.)

(As an aside, this question contains an answer by @kindall that finally helped me to understand - the why, not the how. Unfortunately it's been marked as a duplicate of this one, which I think is a mistake.)


45



When there are certain statements in our module (M.py) we want to be executed when it'll be running as main (not imported), we can place those statements (test-cases, print statements) under this if block.

As by default (when module running as main, not imported) the __name__ variable is set to "__main__", and when it'll be imported the __name__ variable will get a different value, most probably the name of the module ('M'). This is helpful in running different variants of a modules together, and separating their specific input & output statements and also if there are any test-cases.

In short, use this 'if __name__ == "main" ' block to prevent (certain) code from being run when the module is imported.


38



Let's look at the answer in a more abstract way:

Suppose we have this code in x.py:

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

Blocks A and B are run when we are running "x.py".

But just block A (and not B) is run when we are running another module, "y.py" for example, in which x.y is imported and the code is run from there (like when a function in "x.py" is called from y.py).


31