Pythonにおける-mの典型的な用法、原理解析と発展発展

5562 ワード

コマンドラインでPythonを使用すると、約20のオプション(option)を受信できます.構文フォーマットは次のとおりです.
python [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | - ] [args]

本文は比較的に特殊な「-m」オプションについて話したい:その典型的な用法、原理解析と発展の発展の過程について.
まず、「--help」で説明を見てみましょう.
-m mod run library module as a script (terminates option list)
「mod」は「module」の略で、「-m」オプションの後ろにある内容はmodule(モジュール)で、モジュールをスクリプトとして実行する役割を果たします.
「terminates option list」は「-m」以降の他のオプションが機能しないことを意味し、この点では「-c」と同様に「究極のオプション」である.公式には「インタフェースオプション」(Interface options)と定義されており、他の一般的なオプションや一般的なオプションと区別する必要があります.
-mオプションの5つの一般的な使い方
Pythonには-mオプションを使うシーンがたくさんありますが、皆さんが使ったり見たりしたことがあると信じています.ここで5つ共有したいと思います.
Python 3では、1行のコマンドで簡単なHTTPサービスを実現できます.
python -m http.server 8000

#  :  Python2     
python -m SimpleHTTPServer 8000

実行後、ネイティブで「http://localhost:8000」、またはローカルエリアネットワーク内の他のマシンで「http://ネイティブip:8000」を開くと、実行ディレクトリの下のコンテンツにアクセスできます.例えば、下の図が私のネイティブのコンテンツです.
これと同様に、1行のコマンド「python-m pydoc-p xxx」だけで、ブラウザでアクセスできるHTML形式の公式ヘルプドキュメントを生成できます.
上のコマンドはpydocモジュールを実行し、9000ポートでhttpサービスを起動し、ブラウザで開きます.私の結果は次の通りです.
3つ目の一般的な方法は、pdbのデバッグコマンド「python-m pdb xxx.py」を実行し、デバッグモードで「xxx.py」スクリプトを実行することです.
4番目に役立つシーンは、timeitを使用してコマンドラインでコードの実行時間をテストすることです.以下の3セグメントコードは、「0-1-2-......-99」数字列を異なる方法でつづる.効率の違いを直感的に見ることができます.
最後に、「python-m pip install xxx」という無視されるシーンもあります.「pip install xxx」を習慣的に使うか、バージョン区分をするときに「pip 3 install xxx」を使うか、とにかく前に「python-m」で指定しないかもしれません.しかし、このような書き方は問題があるかもしれません.
偶然なことに、今月初め(2019.11.01)、Pythonのコア開発者で第1回指導委員会の5人のメンバーの1人であるBrett Cannonはブログ「Why you should use「python-m pip」を専門に書き、「python-m pip」を使うべきだと提案し、詳細な説明をした.
彼の主な観点は、複数のPythonバージョンが存在する環境では、この書き方は三方ライブラリのインストール位置を正確に制御できるということです.たとえば「python 3.8-m pip」を使用すると、他のバージョンと混同することなく、3.8バージョンのインストールに明確に指定できます.
(延長:Brettについての記事ですが、「Pythonライブラリをインストールしていた姿勢が間違っていたのか!」という短いまとめがあります.
-mオプションの2つの原理解析
前のいくつかの典型的な使い方を見て、「-m」はどのように動作しているのか知りたいですか?どうやって実現したの?
「python-m name」の場合、Pythonはsys.pathを検索し、「name」という名前のモジュールまたはパッケージ(ネーミングスペースパッケージを含む)を検索し、その内容を「_main_」とするを使用して実行できます.
1、一般モジュールについて
「.py」を接尾辞とするファイルはモジュールであり、「-m」の後に使用する場合はモジュール名のみを使用し、接尾辞を書く必要はありませんが、そのモジュール名が有効であり、C言語で書かれたモジュールではないことを前提としています.
「-m」の後、無効なモジュール名の場合、「No module named xxx」とエラーが表示されます.
接尾辞付きモジュールの場合は、まずモジュールがインポートされ、エラーが発生する可能性があります:Error while finding module specification for'xxx.py' (AttributeError: module 'xxx' has no attribute '__path__'.
通常のモジュールでは、この2つの書き方の表面が等価に見える場合があります.
どちらの書き方も、位置決めされたモジュールスクリプトをメインプログラムのエントリとして実行します.すなわち、実行時に、そのスクリプトの__name__はすべて""です.main__」というのは、importの導入方式とは違います.
ただし、実行ディレクトリに「test.py」が存在し、唯一の「test」モジュールしか存在しないことを前提としています.この例では、ディレクトリを変更して実行すると、「python test.py」はもちろんファイルが見つからないエラーを報告しますが、「python-m test」は、解釈器がsys.pathを遍歴したときに同じ名前の「test」モジュールを見つけ、実行できるため、エラーは報告されません.
この違いから、「-m」の使い方をまとめることができます.モジュールの名前は既知ですが、ファイルのパスがわかりません.「-m」を使用すると、解釈器に渡して自分で検索し、見つけたらスクリプトとして実行することを意味します.
前述の「python-m http.server 8000」の例では、「server」モジュールの絶対パスを見つけて実行することもできますが、これは面倒になります.
では,「-m」方式は直接スクリプトを実行するのと比較して,実装上どのような違いがあるのでしょうか.
  • スクリプトを直接実行する場合、絶対パスでも相対パスでもスクリプトの完全なパスが与えられることに相当し、解釈器はファイルシステムの検索メカニズムに基づいてスクリプトにナビゲートし、
  • を実行する.
  • 「-m」方式を使用する場合、解釈器はimportなしですべてのモジュールネーミングスペースで検索し、スクリプトのパスにナビゲートして実行する必要があります.このプロセスを実現するために、解釈器は、モジュール名に基づいてスクリプト
  • を位置決めし実行する2つのモジュール:pkgutilおよびrunpyを使用する.
    2、パッケージ内モジュールについて
    「-m」の後に実行するパケットが1つである場合、解釈器は前述の検索プロセスを経て、パケットにナビゲートし、その後、その「_main_」を実行する.サブモジュール、すなわち、パケットディレクトリの下に「_main_.py」ファイルを実装する必要がある.
    すなわち、パッケージの名前が「pname」であると仮定すると、「python-m pname」は、実際には「python-m pname._main_」に等しい.
    以前にHTTPサービスを作成した例では、「http」はPythonに内蔵されたパッケージであり、「_main_.py」ファイルがないため、「-m」方式で実行すると、No module named http.」とエラーが表示されます.main__; 'http' is a package and cannot be directly executed.
    対照的に、前に述べたpipもパッケージですが、なぜ「python-m pip」が使えるのでしょうか.もちろん「_main_.py」ファイルがあるからです.
    「python-m pip」は、コアの「pip._internal.main」を呼び出す呼び出しエントリとして主に使用されるこの「_main_.py」ファイルを実際に実行します.
    httpパッケージには統合されたエントリモジュールがないため、「python-mパッケージ.モジュール」方式が採用されているが、pipパッケージには統合されたエントリモジュールがあるため、「_main_.py」ファイルが追加され、最後に「python-mパッケージ」と書くだけで、簡明で直感的である.
    -mオプションの10年間の進化
    最初に-mオプションを導入したのはPython 2.4バージョン(2004年)で、当時は機能が制限されていて、pdbやprofileなどの一般的な内蔵モジュールにしか機能しませんでした.
    その後、有名な開発者Nick Coghlanが提案した「PEP 338--Executing modules as scripts」は、その機能を段階的に向上させた.このPEPは2004年に提案され,最終的に2006年の2.5バージョンで実現された.
    (余談ですが、Nick Coghlanはコア開発者のコアの1つであり、第1回指導委員会の5人のメンバーの1人でもあります.当初は材料を見ていましたが、2005年にコア開発者に選ばれたのを覚えています.この時間はPEP-338の時間と密接に合っています)
    このPEPのいくつかのコアポイントは
  • はPEP-302の新しいプローブ機構(new import hooks)と結合し、解釈器がパケット内モジュールを検索する能力
  • を向上させた.
  • は他の導入機構(例えばzipimportとフリーズモジュール(frozen modules))を結合し、解釈器ルックアップモジュールの範囲と精度
  • を広げた.
  • は、CPythonインタプリタを変更することなく、本機能を実現するための新しいrunpy.run_module(modulename)を開発し、他のインタプリタ
  • に容易に移植することができる.
    これで、-mオプションにより、Pythonはすべてのネーミングスペース内でコマンドラインで指定されたモジュールに位置決めできます.
    2009年、Python 3.1バージョンでは、パッケージの名前を指定するだけで、その「_main_」を位置決めして実行できます.サブモジュール.2014年、-mはネーミングスペースパッケージをサポートするまで拡張された.
    これで、10年の発展と変化を経て、-mオプションは機能がそろって、翼が豊満になりました.
    最後に、endingをしましょう.-mオプションは目立たないように見えますが、コマンドラインでモジュール、標準パッケージ、サードパーティライブラリを内蔵するときに便利になります.機会があればもっと使って、それがもたらす喜びを体得しましょう.
    きじゅんざいりょう
    https://docs.python.org/3.7/using/cmdline.html#cmdoption-m
    https://snarky.ca/why-you-should-use-python-m-pip
    https://www.python.org/dev/peps/pep-0338/
    https://blog.csdn.net/jian3x/article/details/89556592
    公众号【Python猫】は、ニャンコ哲学猫シリーズ、Python进阶シリーズ、良い本の推荐シリーズ、技术の作文、良质な英语の推荐と翻訳など、良质なシリーズの文章を连载しています.