怠け者のためのコマンドライン引数処理: Python の argparse モジュール

怠け者のためのコマンドライン引数処理: Python の argparse モジュール

皆さんと同じように、私もタスクを実行するために使い捨てのスクリプトをたくさん書いています。これらは、清掃やメンテナンスのタスクを実行する、20行ほどの簡潔でドキュメント化されていないコードの塊で、書いたらすぐに削除されます。

しかし、何かを永続させるつもりなら、ドキュメントとコメント、ログ記録、サブコマンドのエラーのチェック、適切な失敗、そしてコマンドライン引数の処理など、より専門的なアプローチを取るようにしています。

実際、スクリプトがコマンドライン引数を処理するかどうかが、そのコードが永続的なものになるか使い捨てになるかを決めることが多いことに気づきました。一度だけ特定のことを行うように設計されたコードには設定ノブは必要ありませんが、複数の異なる方法で動作できるコードは、多くの場合、耐久性のあるツールであることを意味します。

この記事では、Pythonの非常に優れたargparseモジュールの使い方をご紹介します。シェルやPerlの経験がある方は、一般的なgetoptsとは少し違うことに気付くでしょう。Golangなどの「大規模」言語のパースに近いと言えるでしょう。

この場合、次のオプションを使用してコードを記述します。

  • -f は処理するファイルを指定します
  • -v は詳細(デバッグ)出力をオンにします

ご覧のとおり、Python はヘルプ出力 (-h) を自動的に含めます。

簡単なコードを見てみましょう。Python 2は廃止されたため、Python 3を使用します。上記の要件を実装する方法は次のとおりです。

私は次の内容を gronkulator.py (技術文書からテレビ番組まであらゆるもので使用される適切なナンセンスワード) に保存しました。

 #!/usr/bin/python3

argparseをインポートする
インポートOS
インポートシステム

def debug(メッセージ):
    args.wants_debugの場合:
        印刷(メッセージ)

parser = argparse.ArgumentParser ( description = '往復型量子間グロンキュレータ' )
parser.add_argument('-f', help="処理するファイル", dest="ファイル名", 
    アクション='ストア'、必須=True)
parser.add_argument('-v', help="デバッグを有効にする", dest="wants_debug", 
    アクション='store_true'、必須=False、デフォルト=False)
引数 = パーサー.parse_args()

debug ("デバッグ出力をオンにしました")
os.path.exists(args.file_name) == Falseの場合:
    print ("エラー!  ファイル '%s' が存在しません - 中止します" % ( args.file_name ))
    sys.exit(1)

print ("ファイル '%s' を処理中" % ( args.file_name ))

分かりやすくするために、いくつかの行を折り返しました。簡単に説明してみましょう。

 parser = argparse.ArgumentParser ( description = '往復型量子間グロンキュレータ' )

これにより、パーサーオブジェクトが作成されます。ちなみに、コマンドライン引数は必要な回数だけ解析できるので、ローカルで再度解析したい場合は、サブルーチンの奥深くに argparse を組み込んでも構いません。

 parser.add_argument('-f', help="処理するファイル", dest="ファイル名",
    アクション='ストア'、必須=True)
parser.add_argument('-v', help="デバッグを有効にする", dest="wants_debug",
    アクション='store_true'、必須=False、デフォルト=False)

ここで引数を追加します。コードを読むだけで、おそらく理解できるでしょう。-f は処理対象となるファイル名を指定します。このパラメータは必須(True)で、その値は変数「args.file_name」(下記参照)に「保存」されます。

次の行は -v 引数を追加します。これはオプションで、設定されている場合、変数「args.wants_debug」がTrueに、設定されていない場合はFalseに設定されます。これは非常に便利です。この行以降、args.wants_debug変数が正しい値で存在することが保証され、どこからでも参照できるようになります。

引数 = パーサー.parse_args()

そして、これが実際の引数解析を行います。作成された 'args' 変数には、“dest” 変数に対応する値(args.file_name、args.wants_debug など)が設定されます。

その後、debug() 関数を実行し、file_name が存在するかどうかを確認します。存在しない場合はエラーを出力し、存在する場合は必要な処理を実行します。

コードを試してみましょう:

 # ./gronkulator.py
使用方法: gronkulator.py [-h] -f FILE_NAME [-v]
gronkulator.py: エラー: 次の引数が必要です: -f

ここで、「使用方法」のコードは何も書いていないことに注意してください。すべてPythonによって生成されています。-hオプションを付けて試してみましょう。

 # ./gronkulator.py -h
使用方法: gronkulator.py [-h] -f FILE_NAME [-v]

往復型超量子グロンキュレータ

オプションの引数:
-h, --help    このヘルプメッセージを表示して終了する
-f ファイル名  処理するファイル
-v            デバッグを有効にする

いいですね。Python は完全なヘルプチャートを提供しています。

 # ./gronkulator.py -f /tmp/junk 
ファイル '/tmp/junk' を処理中
# ./gronkulator.py -v -f /tmp/junk 
デバッグ出力をオンにしました
ファイル '/tmp/junk' を処理中

意図したとおりに動作しているようです。-v をオンにするとデバッグ出力が表示され、オフにすると表示されません。スクリプトは -f 引数を取得します。

他にもできることはたくさんあります。省略形や長いフラグの追加から、ヘルプ用のエピローグの追加、sys.argv以外のストリームの解析、既に設定されている変数の処理など、実に多岐にわたります。実際、argparse自体にあまりにも多くのオプションがあり、一部の読者が圧倒されてしまうことが大きな問題です。しかし、基本的な部分、つまりいくつかのフラグを要求し、後でその値にアクセスするという部分は、非常にシンプルで、上記のようなレシピから簡単にコピー&ペーストできると思います。どうぞお楽しみください!

おすすめの記事