Питання Що робити, якщо __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))

4149
2018-01-07 04:11


походження




Відповіді:


Коли інтерпретатор Python читає вихідний файл, він виконує весь знайдене у ньому код.

Перед виконанням коду буде визначено кілька спеціальних змінних. Наприклад, якщо інтерпретатор Python запускає цей модуль (вихідний файл) як основну програму, він встановлює спеціальний інтерпретатор __name__ змінна мати значення "__main__". Якщо цей файл імпортується з іншого модуля, __name__ буде вказано ім'я модуля.

У випадку вашого сценарію, припустимо, що він виконується як основна функція, наприклад ти сказав щось подібне

python threading_example.py

в командному рядку. Після налаштування спеціальних змінних він буде виконувати import викладення і завантаження цих модулів. Тоді вона оцінить def блокувати, створити об'єкт функції і створити змінну, яка викликається myfunction що вказує на об'єкт функції. Потім він прочитає if твердження і побачити це __name__ рівний "__main__", тому він буде виконувати показаний там блок.

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

Побачити ця сторінка для деяких додаткових деталей.


4421
2018-01-07 04:26



Примітка. Якщо ви поставите код перед визначеннями функції, він буде виконуватись перед основним. print("This code executes before main.") def functionA(): print("Function A") def functionB(): print("Function B") if __name__ == '__main__': functionA() functionB()  Цей код дає: This code executes before main. Function A Function B - Stainsor


Коли ваш скрипт запускається, передаючи його як команду інтерпретатору 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__".


1415
2018-01-07 04:28



Блискуче пояснення. - Poles


Найпростіше пояснення для __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__".


562
2018-01-07 11:35





Що таке 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!

І тоді вам доведеться запам'ятати, чи ви прокоментували чи ви не дзвонили про тестову функцію. І ця додаткова складність означає, що ви, швидше за все, забудуть, зробивши процес розробки більш складним.

Кращий шлях

The __name__ змінна вказує на простір імен, де перебуває в даний час перекладач Python.

Усередині імпортованого модуля це назва модуля.

Але всередині основного модуля (або інтерактивного сеансу Python, тобто читання інтерпретатора, Eval, циклу друку або REPL) ви використовуєте все, починаючи з його "__main__".

Отже, якщо ви перевіряєте перед виконанням:

if __name__ == "__main__":
    do_important()

З наведеним вище, ваш код буде виконуватися лише тоді, коли ви використовуєте його як основний модуль (або навмисно називаєте його з іншого сценарію).

Ще кращий спосіб

Тим не менш, існує пітонічний спосіб поліпшити це.

Що робити, якщо ми хочемо запустити цей бізнес-процес за межами модуля?

Якщо ми поставимо код, який ми хочемо здійснити, коли ми розробляємо та тестуємо в такій функції, а потім виконуємо нашу перевірку '__main__' відразу після:

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

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

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

Це дозволить імпортувати модуль, його функції та класи в інші скрипти без запуску main функцію, а також дозволить викликати модуль (і його функції та класи) під час запуску з іншого '__main__' модуль, тобто

import important
important.main()

Ця ідіома також міститься в документації Python в поясненні __main__ модуль У цьому тексті говориться:

Цей модуль являє собою (інакше анонімний) обсяг, в якому   виконується основна програма інтерпретатора - команди читаються або з   стандартний ввід, з файлу сценарію або з інтерактивної підказки. Це   це середовище, в якому йде ідіоматичний "умовний скрипт" строфа   викликає запуск сценарію:

if __name__ == '__main__':
    main()

413
2017-11-23 04:38





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


92
2018-01-07 04:14





Що робить 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()

57
2017-10-14 20:22





Тут багато різних приймає на механіку даного коду, "Як", але для мене жоден з них не мав сенсу, поки я не зрозумів "Чому". Це має бути особливо корисним для нових програмістів.

Введіть файл "ab.py":

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

І другий файл "xy.py":

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

Що це робить цей код?

Коли ви виконуєте xy.py, ви import ab. Запит імпорту запускає модуль негайно після імпорту, таким чином abОперації 's' s виконуються до кінця xyс. Після закінчення ab, він продовжується xy.

Перекладач відстежує, з якими скриптами працюють __name__. Коли ви запускаєте скрипт - незалежно від того, що ви його назвали - інтерпретатор називає це "__main__", що робить його головним або "домашнім" сценарієм, який повертається після запуску зовнішнього сценарію.

Будь-який інший скрипт, який викликається з цього "__main__" Сценарій присвоює своє ім'я файлу як його __name__ (наприклад, __name__ == "ab.py") Отже, лінія if __name__ == "__main__": це тест інтерпретатора, який визначає, чи він інтерпретує / розбирає "домашній" скрипт, який спочатку виконувався, або якщо він тимчасово заглядає в інший (зовнішній) скрипт. Це дає гнучкість програміста в тому, що скрипт веде себе по-різному, якщо він виконується безпосередньо або викликається ззовні.

Давайте пройдемо крізь вищезазначений код, щоб зрозуміти, що відбувається, перш за все орієнтуючись на незрозумілі рядки та порядок їх появи в скриптах. Пам'ятайте цю функцію - або def - блоки не роблять нічого самостійно, доки вони не будуть викликані. Що інтерпретатор міг би сказати, якщо б прозвучав:

  • Відкрийте файл xy.py як домашній файл; назви це "__main__" в __name__ змінна
  • Імпортуйте та відкрийте файл з __name__ == "ab.py".
  • О, це функція. Я це запам'ятаю.
  • Гаразд, функція a(); Я тільки що це дізнався. Друк 'Функція в ab-файлі'.
  • Кінець файлу; повертатися до "__main__"!
  • О, це функція. Я це запам'ятаю.
  • Інший.
  • Функція x(); добре, друк "периферійне завдання: може бути корисним і в інших проектах'.
  • Що це? Ан if заява Ну, умова була виконана (змінна __name__було встановлено на "__main__"), тому я ввійду в main() функція та друк 'основна функція: саме там відбувається дія'.

Дві нижні лінії означають: "Якщо це є "__main__" або "домашній" скрипт, виконайте функцію, яка викликається main()". Тому ви побачите def main(): блокувати верх, що містить основний потік функціональності сценарію.

Чому це здійснювати?

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

Знову ж таки, будуть винятки, але звичайна практика полягає в тому, що main() зазвичай не називається зовнішньо. Так що вам може бути цікаво ще одне: якщо ми не дзвонимо main(), чому ми називаємо скрипт взагалі? Це пов'язано з тим, що багато людей структурують свої скрипти за допомогою окремих функцій, побудованих для запуску незалежно від решти коду в файлі. Потім вони потім називаються куди-небудь ще в тілі сценарію. Що приносить мені це:

Але код працює без нього

Так, правильно. Ці окремі функції може можна викликати з внутрішнього скрипту, який не міститься всередині a main() функція Якщо ви звикли (як я, на моїх ранніх стадіях навчання програмуванню) створювати вбудовані скрипти, які роблять саме те, що вам потрібно, і спробуйте знову зрозуміти це, якщо вам знову потрібна така операція. добре, ви не звикли до такого роду внутрішньої структури вашого коду, тому що це складніше для створення, і це не так інтуїтивно зрозумілий для читання.

Але це скрипт, який, ймовірно, не може мати свої функції ззовні, оскільки якщо він це зробить, він негайно почне обчислити і призначати змінні. І, ймовірно, якщо ви намагаєтеся повторно використовувати функцію, ваш новий скрипт досить близько пов'язаний із старим, що буде конфліктуючі змінні.

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

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


47
2017-09-29 04:33





Коли у нашому модулі є певні твердження (M.py) ми хочемо бути виконані, коли він буде працювати як основний (не імпортований), ми можемо розмістити ці твердження (тести, вирази друку) під цим ifблок

Як за замовчуванням (коли модуль працює як основний, а не імпортований) __name__ змінна встановлена ​​на "__main__", і коли його буде імпортовано __name__ змінна отримає інше значення, найімовірніше, назва модуля ('M') Це корисно для керування різними варіантами модулів разом, а також для розділення їх конкретних введених і вихідних тверджень, а також, якщо існують якісь тестові випадки.

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


39
2018-04-03 14:09





Давайте розглянемо відповідь ще абстрактніше:

Припустимо, у нас цей код в x.py:

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

Блоки A і B запускаються, коли ми використовуємо "x.py".

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


32
2018-01-20 17:48