Не могли бы вы объяснить мне, в чем разница между звонками
python -m mymod1 mymod2.py args
и
python mymod1.py mymod2.py args
Кажется в обоих случаях mymod1.py
называется и sys.argv
есть
['mymod1.py', 'mymod2.py', 'args']
Так для чего -m
нужен переключатель?
python
command-line
module
package
Шарль Брюне
источник
источник
-m
кажется, поискmymod1
в пути по умолчанию библиотеки. Пример:python -m SimpleHTTPServer
работает, аpython SimpleHTTPServer
не сcan't open file 'SimpleHTTPServer': [Errno 2] No such file or directory
.Ответы:
Первая строка
Rationale
раздела PEP 338 гласит:Таким образом, вы можете указать любой модуль в пути поиска Python, а не только файлы в текущем каталоге. Вы правы, что
python mymod1.py mymod2.py args
имеет точно такой же эффект. Первая строкаScope of this proposal
раздела гласит:С помощью
-m
большего возможно, например, работать с модулями, которые являются частью пакета, и т. Д. Это то, что представляет собой остальная часть PEP 338. Прочитайте это для получения дополнительной информации.источник
-m
этоpython -m SimpleHTTPServer
. Очень удобно, когда мне нужно поделиться некоторыми файлами без использования USB-накопителя.python -m http.server
и это все еще круто!python -m package.subpackage.module
и использовать обычное разрешающее оборудование, вам не нужно указывать точный.py
файл. 2) Можно выполнить относительный импорт из запущенного модуля без каких-либо обходных путей, потому что его пакет будет загружен по пути. 3) Абсолютный импорт будет основываться на вашем текущем каталоге, а не на каталоге, в котором находится.py
файл (''
находится во главеsys.path
, а не в том/path/to/my
случае, если скрипт находится в/path/to/my/script.py
).__main__.py
файлом. Большинство не делает и сломается, например,python -m sys 'print(sys.version)'
терпит неудачуpython: No code object available for sys
. Предлагаю вам сделать это ясно в ответе.Стоит отметить, что это работает, только если в пакете есть файл.
__main__.py
В противном случае этот пакет не может быть выполнен напрямую.Интерпретатор python будет искать
__main__.py
файл в пути пакета для выполнения. Это эквивалентно:Он выполнит содержимое после:
источник
Несмотря на то, что на этот вопрос задавали и отвечали несколько раз (например, здесь , здесь , здесь и здесь ), по моему мнению, ни один из существующих ответов полностью или кратко не отражает все значения
-m
флага. Поэтому следующее попытается улучшить то, что было раньше.Введение (TLDR)
Команда
-m
делает много вещей, не все из них обязательно будут нужны постоянно. Вкратце: (1) позволяет выполнять сценарии Python с помощью modulename, а не имени файла (2) позволяет выбрать каталог для добавленияsys.path
дляimport
разрешения и (3) позволяет выполнять сценарии Python с относительным импортом из командной строки. ,прелиминарии
Чтобы объяснить
-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.источник
python -m packagename
как указано здесь: stackoverflow.com/a/53772635/1779091