Незважаючи на запитання та відповіді на це кілька разів (наприклад, тут , тут , тут , і тут ), на мою думку, жодна з існуючих відповідей повністю чи стисло не відображає всіх наслідків -mпрапора. Тому далі буде намагатися покращити те, що було раніше.
Вступ (TLDR)
-mКоманда робить багато речей , не всі з них обов'язково будуть потрібні весь час. Коротше кажучи: (1) дозволяє пітон, щоб скрипти виконувалися з допомогою MODULENAME , а не ім'я файлу (2) дозволяє вибрати каталог , щоб додати до sys.pathдля importдозволу і (3) дозволяє пітон сценарії з відносно імпорту повинні бути виконані з командного рядка .
Прелімінарії
Щоб пояснити -mпрапор, спершу треба чітко визначити термінологію.
По-перше, первинний організаційний підрозділ Python відомий як модуль . Модуль поставляється в одному з двох варіантів: кодові модулі та модулі пакетів. Модуль коду - це будь-який файл, який містить виконуваний код python. Пакетний модуль - це каталог, який містить інші модулі (або модулі коду, або пакети). Найпоширенішим типом модулів коду є *.pyфайли, тоді як найпоширеніший тип модулів пакету - це каталоги, що містять __init__.pyфайл.
По-друге, всі модулі можна однозначно ідентифікувати двома різними способами: <modulename>та <filename>. Модулі найчастіше ідентифікуються за іменем модуля в коді Python (наприклад, import <modulename>) та за назвою файлу в командному рядку (наприклад, python <filename>). Усі інтерпретатори Python можуть перетворювати модулемени у назви файлів через набір чітко визначених правил. Ці правила залежать від sys.pathзмінної, і тому відображення можна змінити, змінивши це значення (докладніше про те, як це робиться, див. PEP 302 ).
По-третє, всі модулі (і код, і пакет) можуть бути виконані (під яким ми маємо на увазі код, пов'язаний з модулем, буде оцінено інтерпретатором Python). Залежно від способу виконання та типу модуля, який код оцінюється та коли, може змінитися зовсім небагато. Наприклад, якщо хтось виконує пакетний модуль до python <filename>цього часу, <filename>/__init__.pyвін буде оцінюватися з подальшим виконанням <filename>/__main__.py. З іншого боку, якщо хтось виконує той самий модуль пакету, import <modulename>тоді виконуватимуться лише пакети __init__.py.
Історичний розвиток Росії -m
Прапор -m вперше було введено в Python 2.4.1 . Спочатку його єдиною метою було створення альтернативного способу ідентифікації модуля python для виконання. Тобто, якщо ми знали <filename>і <modulename>модуль, і модуль, наступні дві команди були еквівалентними: python <filename> <args>і python -m <modulename> <args>. Крім того, згідно з PEP 338, ця ітерація -mпрацювала лише з модуленами верхнього рівня (тобто модулями, які можна було знайти безпосередньо на sys.path без будь-яких пакетів, що втручалися).
Із завершенням PEP 338-m функціональність була розширена для підтримки <modulename>уявлень за межами верхніх modulenames рівня. Це означало імена, http.serverякі зараз повністю підтримуються. Це вдосконалення також означало, що зараз завантажуються всі пакунки в модулі (тобто всі __init__.pyфайли пакетів оцінювалися) разом із самим модулем.
Кінцеве значне підвищення функції для -mприйшло з PEP 366 . За допомогою цього оновлення -mнабула можливість підтримувати не лише абсолютний імпорт, але й явний відносний імпорт. Це було досягнуто шляхом зміни __package__змінної для названого модуля в -mкоманді.
Використовуйте випадки
Є два помітні випадки використання прапора -m:
Виконати модулі з командного рядка, для якого можна не знати їх імені файлів. Цей випадок використання використовує той факт, що інтерпретатор Python знає, як перетворити модулемени у назви файлів. Це особливо вигідно, коли потрібно запускати stdlib модулі або сторонні модулі з командного рядка. Наприклад, дуже мало людей знають ім'я файлу для http.serverмодуля, але більшість людей знають його ім'я, тому ми можемо виконати його з командного рядка за допомогою python -m http.server.
Виконати локальний пакет, що містить абсолютний імпорт без необхідності його встановлення. Цей випадок використання детально описаний у PEP 338 і використовує той факт, що поточний робочий каталог додається до sys.pathкаталогу модуля. Цей випадок використання дуже схожий на pip install -e .встановлення пакета в режимі розробки / редагування.
Недоліки
З урахуванням усіх удосконалень -mпротягом багатьох років у нього все ще є один головний недолік - він може виконувати лише кодові модулі, написані в python (тобто * .py). Наприклад, якщо -mвикористовується для виконання модуля коду, зібраного на C, буде створено наступну помилку No code object available for <modulename>(див. Тут для більш детальної інформації).
Детальні порівняння
Ефекти виконання модуля за допомогою команди python (тобто, python <filename>):
sys.path модифікується, щоб включати остаточний каталог у <filename>
__name__ встановлено на '__main__'
__package__ встановлено на None
__init__.py не оцінюється для жодного пакету (включаючи його власний для модулів пакету)
__main__.pyоцінюється для пакетних модулів; код оцінюється для модулів коду.
Ефекти виконання модуля через оператор імпорту (тобто import <modulename>):
sys.pathце НЕ змінені будь - яким чином
__name__ встановлюється в абсолютній формі <modulename>
__package__ встановлено для безпосереднього батьківського пакета в <modulename>
__init__.py оцінюється для всіх пакетів (включаючи власні для пакетних модулів)
__main__.pyце НЕ оцінюється для модулів пакетів; код оцінюється для модулів коду
Ефекти виконання модуля через прапор -m (тобто python -m <modulename>):
sys.path модифікується для включення поточного каталогу
__name__ встановлено на '__main__'
__package__ встановлено для безпосереднього батьківського пакета в <modulename>
__init__.py оцінюється для всіх пакетів (включаючи власні для пакетних модулів)
__main__.pyоцінюється для пакетних модулів; код оцінюється для модулів коду
Висновок
-mПрапор, в найпростішому, засіб для виконання пітона сценаріїв з командного рядка за допомогою modulenames , а не імена файлів. Крім того, -mнадається додаткова функціональність, яка поєднує в собі потужність importоператорів (наприклад, підтримка явного відносного імпорту та автоматична __init__оцінка пакету ) із зручністю командного рядка python.
-mздається, шукаєmymod1шлях до бібліотеки за замовчуванням. Приклад:python -m SimpleHTTPServerпрацює, тоді якpython SimpleHTTPServerне вдаєтьсяcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory.