Python argparseでブール値を扱う注意点:コマンドライン引数の「True/False」を正しく解析する!


 

Pythonの**argparse**モジュールは、コマンドライン引数を扱う上で非常に強力なツールです。しかし、**ブール値(True/False)**を引数として渡す際には、少し注意が必要です。一般的なbool型変換の感覚で扱おうとすると、予期せぬ挙動に遭遇することがあります。この記事では、argparseでブール値を安全かつ正確に扱うためのベストプラクティスを、具体的なコード例を交えながら解説します。


 

なぜargparseでブール値が特殊なのか?

 

Pythonのbool()関数は、空でない文字列をTrueと評価します。

Python
 
bool("False")  # 結果は True

この挙動のため、argparsetype=boolを指定して引数を解析しようとすると、コマンドラインから渡された "False" という文字列もTrueとして扱われてしまいます。これが、argparseでブール値を直接type=boolで扱うべきではない主な理由です。


 

argparseでブール値を扱う正しい方法

 

argparseでは、ブール値を扱うために主にaction引数を使用します。

 

1. action='store_true'action='store_false' を使う

 

これが、argparseでブール値を扱う最も一般的で推奨される方法です。

  • action='store_true':

    • このオプションがコマンドラインで指定された場合、対応する引数の値はTrueになります。

    • 指定されなかった場合、デフォルト値(通常はFalse)になります。

    • フラグとして機能させたい場合に最適です(例: --verbose)。

  • action='store_false':

    • このオプションがコマンドラインで指定された場合、対応する引数の値はFalseになります。

    • 指定されなかった場合、デフォルト値(通常はTrue)になります。

    • デフォルトで有効な設定を無効にする場合に利用できます(例: --no-cache)。

 

コード例

 

Python
 
# boolean_flag.py
import argparse

parser = argparse.ArgumentParser(description="ブール値フラグの例")

# --verboseが指定されたらTrue、されなかったらFalse (デフォルト)
parser.add_argument('--verbose', action='store_true',
                    help='詳細なメッセージを表示します')

# --no-cacheが指定されたらFalse、されなかったらTrue (デフォルト)
parser.add_argument('--no-cache', action='store_false', dest='use_cache',
                    help='キャッシュを使用しません')

args = parser.parse_args()

print(f"詳細モード (verbose): {args.verbose}")
print(f"キャッシュ使用 (use_cache): {args.use_cache}")

 

実行例

 

Bash
 
# --verboseを指定した場合
python boolean_flag.py --verbose
# 出力:
# 詳細モード (verbose): True
# キャッシュ使用 (use_cache): True

# --no-cacheを指定した場合
python boolean_flag.py --no-cache
# 出力:
# 詳細モード (verbose): False
# キャッシュ使用 (use_cache): False

# どちらも指定しない場合
python boolean_flag.py
# 出力:
# 詳細モード (verbose): False
# キャッシュ使用 (use_cache): True

ポイント:

  • action='store_true'のデフォルト値はFalseです。

  • action='store_false'のデフォルト値はTrueです。(destで結果が格納される属性名を指定しない場合、デフォルトでno_cache属性にFalseが格納されますが、この例ではuse_cacheFalseが格納されます)。

 

2. 明示的な文字列をブール値に変換する(カスタム関数)

 

ユーザーに--debug true--debug falseのように明示的にtrueまたはfalseを引数として指定させたい場合は、カスタム関数をtype引数に渡して変換する方法があります。

Python
 
# custom_boolean.py
import argparse

def str_to_bool(value):
    """文字列 'true'/'false' をブール値に変換するカスタム関数"""
    value = value.lower()
    if value in ('yes', 'true', 't', 'y', '1'):
        return True
    elif value in ('no', 'false', 'f', 'n', '0'):
        return False
    else:
        raise argparse.ArgumentTypeError(f"'{value}' は有効なブール値ではありません。")

parser = argparse.ArgumentParser(description="カスタムブール変換の例")

parser.add_argument('--debug', type=str_to_bool, default=False,
                    help='デバッグモードのオン/オフ (true/false)')

args = parser.parse_args()

print(f"デバッグモード: {args.debug}")
print(f"型: {type(args.debug)}")

 

実行例

 

Bash
 
python custom_boolean.py --debug true
# 出力:
# デバッグモード: True
# 型: <class 'bool'>

python custom_boolean.py --debug False
# 出力:
# デバッグモード: False
# 型: <class 'bool'>

python custom_boolean.py --debug invalid
# 出力:
# usage: custom_boolean.py [-h] [--debug {true|false}]
# custom_boolean.py: error: argument --debug: 'invalid' は有効なブール値ではありません。

ポイント: この方法を使えば、ユーザーがtruefalseを明示的に指定できますが、action='store_true'/store_false'の方がシンプルで、引数が存在するかどうかだけでブール値を判断できるため、より一般的です。


 

まとめ

 

argparseでブール値を扱う際の最も安全で推奨される方法は、**action='store_true'またはaction='store_false'**を使用することです。これにより、コマンドライン引数の有無によってブール値が自動的に設定され、type=boolによる予期せぬ挙動を避けることができます。

もし、ユーザーが明示的にtrue/falseなどの文字列を入力することを許可したい場合は、カスタムの型変換関数を定義することで対応可能です。適切な方法を選択し、堅牢で使いやすいコマンドラインツールを構築しましょう。

ご自身のプロジェクトでどちらの方法が適しているか、ぜひ試してみてくださいね!

■プロンプトだけでオリジナルアプリを開発・公開してみた!!

■AI時代の第一歩!「AI駆動開発コース」はじめました!

テックジム東京本校で先行開始。

■テックジム東京本校

「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。

<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。

<月1開催>放送作家による映像ディレクター養成講座

<オンライン無料>ゼロから始めるPython爆速講座