Pythonで引数解析をする方法

Python

約半年ぶりにブログを書きました、mk419です。

半年の間に大学受験という大きなイベントがありました。結果は前期落ちて、後期での合格になりました・・・( 共通テストの数学許せねぇ

正直半年間Linuxとかプログラミングとかから離れていたのでネタがありません()
(気が向いたらWaydroid関連のネタを書きます)

今回はハヤオ氏がBashでやっていたことのPython版です。以下にハヤオ氏の記事を置いておきます。

https://blog.fascode.net/2022/01/25/bash-bsd-parse-args/
スポンサーリンク

方法その1 getopt

前述した記事ではgetoptを使って、引数解析をしていました。Pythonにも同名の標準ライブラリがあるので、それを利用したやり方です。

結論から言うとオススメしません

C言語のgetoptに慣れ親しんだ人のためにあるライブラリなので、Pythonの標準ライブラリで引数解析するなら次の方法を使ったほうが遥かに楽です。

前置きはこれぐらいにして、以下コードです。

import getopt
import sys

if __name__ == "__main__":
    try:
        optlist, args = getopt.getopt(sys.argv[1:], "a:bh", ["aa=", "bb", "help"])
    except getopt.GetoptError as error:
        print(error)
        sys.exit(1)

    for opt, value in optlist:
        match opt:
            case "-a" | "--aa":
                print(value)
            case "-b" | "--bb":
                print("-bか--bbが選択されました")
            case "-h" | "--help":
                print("使い方: -a <引数> -b -h")
                sys.exit()

※今回のコードではPython 3.10で導入されたMatch文を使用しています。それ以前のバージョンを使用している場合はif文に置き換えてください。

Bashのgetoptと大体一緒です。「getopt.getopt()」の第3引数の設定が少しだけ違うぐらいです。引数を取る場合だけ「:」の変わりに「=」をつけます。

optlistの方にオプションと引数が入ったタプルのリストが代入されるので、それをforループで取り出して解析しています。

方法その2 argparse

公式が推奨している標準ライブラリのargparseを使用した方法です。

以下コード

import argparse
import sys

parser = argparse.ArgumentParser()
parser.add_argument("-a", "--aa")
parser.add_argument("-b", "--bb", action='store_true')

if __name__ == "__main__":
    args = parser.parse_args(sys.argv[1:])

    for key, value in vars(args).items():
        match key:
            case "aa":
                print(value)
            case "bb":
                if args.bb:
                    print("-bか--bbが選択されました")

だいぶスッキリしてわかりやすくなりました。

「-b」が引数をとらないオプションなので、「store_true」を指定することでTrueを代入させています。「args」はObjectなので「vars()」でDict型に変換しています。「args.<ロングオプション名>」で値を取り出すことができます。argparseは使用方法を自動で生成してくれるので、「-h」を指定する必要がありません。getoptよりかなり楽で分かりやすいので、標準ライブラリを使用するならオススメです。

方法その3 Typer

最近流行っていて、自分も推しているFast APIというライブラリがあります。DjangoとかFlaskみたいなやつです。それのコマンドライン版としてTyperというものがあります。オプションとか引数とかを楽に解析できます。

pip install typer

yay -S python-typer 

でインストールしてください。

以下コード

import typer

def main(
    aa: str = typer.Option(None, "-a", "--aa"),
    bb: bool = typer.Option(None, "-b", "--bb")
) -> None:
    if aa:
        print(aa)

    if bb:
        print("-bか--bbが選択されました")

if __name__ == "__main__":
    typer.run(main)

すごいシンプル。

「aa」に「–aa」の引数が自動で代入されます。「bb」の方にはbool型が代入されます。さっきのargparseでは色々指定してましたが、こっちはbool型を指定さえすれば勝手にやってくれます。もちろん使用方法も生成してくれるので、「-h」の指定は必要ありません。

終わりに

Pythonはライブラリが非常に強力なので、ファイルを肥大化させたくないといった考えがないなら使用したほうが楽です。コードを書く上で大きく時間を節約できるのであなたも外部ライブラリ使ってみませんか?

正直requestsは標準ライブラリになってもいいんじゃないかと個人的には思っています。

コメント

タイトルとURLをコピーしました