Pythonのargparseでブール値を扱うときは注意が必要

Modified: | Tags: Python

Pythonでコマンドライン引数を扱うには、sysモジュールのargvかargparseモジュールを使う。

argparseモジュールを使うとコマンドライン引数を柔軟に処理できるが、ブール値(True, False)を扱う場合は注意が必要。

なお、本記事ではargparseモジュールにおけるブール値の取り扱いにフォーカスして説明する。argparseの基本的な使い方などは公式のチュートリアルを参照。

add_argument()typeで引数の型を指定

argparseで便利なのが、型の指定。

add_argument()の引数typeで型を指定できる。例えば、整数intを指定するとコマンドライン引数が自動でintに変換される。intに変換できない値に対してはエラーになる。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('arg_int', type=int)

args = parser.parse_args()
print(args.arg_int)
print(type(args.arg_int))

このファイルをコマンドラインから実行する。

$ python argparse_type_int.py 100
100
<class 'int'>

コマンドライン引数100intとして読み込まれる。

intに変換できない値をコマンドライン引数とするとエラーが発生する。想定外の値を弾けるので便利。

$ python argparse_type_int.py abc
usage: argparse_type_int.py [-h] arg_int
argparse_type_int.py: error: argument arg_int: invalid int value: 'abc'

$ python argparse_type_int.py 1.23
usage: argparse_type_int.py [-h] arg_int
argparse_type_int.py: error: argument arg_int: invalid int value: '1.23'

add_argument()typeboolを指定してはいけない

注意が必要なのがboolintfloatなどのようにadd_argument()の引数typeboolを指定すると想定外の結果となる。

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('arg_bool', type=bool)

args = parser.parse_args()
print(args.arg_bool)
print(type(args.arg_bool))

このファイルをコマンドラインから実行する。

$ python argparse_type_bool.py True
True
<class 'bool'>

Trueを引数とするとbool型のTrueとして読み込まれる。これは想定通りの動作だが、問題は次の場合。

$ python argparse_type_bool.py False
True
<class 'bool'>

$ python argparse_type_bool.py abc
True
<class 'bool'>

Falseや他の文字列を引数にしてもTrueとして読み込まれてしまう。

これはadd_argument()type=xxxと指定すると引数がxxx()に渡されるのが原因。

例えば、type=intとするとint()に、type=floatとするとfloat()に引数が渡される。int(), float()は文字列をint, floatに変換する。

type=boolの場合も同じで、引数がbool()に渡されることになる。

bool()による判定の注意点

bool()は引数の値を判定しTrueまたはFalseを返す。

以下のオブジェクトは偽と判定される。

それ以外のオブジェクトはすべて真と判定される。したがって、'True'でも'False'でも、空ではない文字列をbool()に渡すとすべてTrueが返される。空文字列のみがFalseとなる。

print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True

print(bool(''))
# False
source: bool_test.py

add_argument()type=boolとするとコマンドライン引数がbool()に渡されるため、例えばFalseを引数とすると文字列'False'としてbool()で変換され、Trueとして読み込まれてしまう。

action'store_true', 'store_false'を指定

argparseでブール値を使いたい場合、引数typeではなく引数action'store_true'または'store_false'を指定する。

'store_true', 'store_false' - これらは 'store_const' の、それぞれ TrueFalse を格納する特別版になります。加えて、これらはそれぞれデフォルト値を順に FalseTrue にします。 argparse - action — Python 3.13.3 ドキュメント

import argparse

parser = argparse.ArgumentParser()
parser.add_argument('--en', action='store_true')

args = parser.parse_args()
print(args.en)
print(type(args.en))

オプション--xxx(例では--en)をつけるとxxx(例ではen)がTrueとして、つけないとデフォルト値のFalseとして読み込まれる。

$ python argparse_option_bool.py --en
True
<class 'bool'>

$ python argparse_option_bool.py
False
<class 'bool'>

デフォルトをTrueにしてオプションをつけたときにFalseとしたい場合は、action='store_false'とすればよい。

strtobool()を使う

オプションではなく位置引数を使いたい場合は、strtobool()を使う方法もある。

strtobool()は文字列の内容に応じて真偽を返す関数。

Python 3.11までは標準ライブラリのdistutils.utilモジュールに含まれていたが、Python 3.12でdistutilsパッケージが削除された。Python 3.12以降はサードパーティライブラリのsetuptoolsで使用可能(pipなどでインストールが必要)。

# For Python 3.11 and earlier
from distutils.util import strtobool

# For Python 3.12 and later (requires installing setuptools)
from setuptools._distutils.util import strtobool

以下の文字列が対象。大文字小文字の区別はなく'TRUE''True'なども'true'と同じ扱い。それ以外の文字列はエラーになる。

  • 真: 'y', 'yes', 't', 'true', 'on', '1'
  • 偽: 'n', 'no', 'f', 'false', 'off', '0'

真の値は y, yes, t, true, on そして 1 です。偽の値は n, no, f, false, off そして 0 です。 val が上のどれでもない時は ValueError を起こします。
9. API リファレンス - distutils.util.strtobool() — Python 3.11.7 ドキュメント

以前は整数int1または0を返していたが、setuptoolsのバージョン75.3.2(2025/03/12リリース)からTrueまたはFalseを返すようになった。

from setuptools._distutils.util import strtobool

print(strtobool('true'))
print(strtobool('True'))
print(strtobool('TRUE'))
# True
# True
# True

print(strtobool('t'))
print(strtobool('yes'))
print(strtobool('y'))
print(strtobool('on'))
print(strtobool('1'))
# True
# True
# True
# True
# True

print(strtobool('false'))
print(strtobool('False'))
print(strtobool('FALSE'))
# False
# False
# False

print(strtobool('f'))
print(strtobool('no'))
print(strtobool('n'))
print(strtobool('off'))
print(strtobool('0'))
# False
# False
# False
# False
# False

# print(strtobool('abc'))
# ValueError: invalid truth value 'abc'

上述のように、argparseのadd_argument()type=xxxと指定すると引数がxxx()に渡されるので、type=strtoboolとすればよい。

import argparse

from setuptools._distutils.util import strtobool

parser = argparse.ArgumentParser()
parser.add_argument('arg_bool', type=strtobool)

args = parser.parse_args()
print(args.arg_bool)
print(type(args.arg_bool))

truefalseなどの文字列の引数を真偽の値として読み込むことができる。

$ python argparse_type_strtobool.py true
True
<class 'bool'>

$ python argparse_type_strtobool.py false
False
<class 'bool'>

想定外の引数の場合はエラーが発生する。

$ python argparse_type_strtobool.py abc
usage: argparse_type_strtobool.py [-h] arg_bool
argparse_type_strtobool.py: error: argument arg_bool: invalid strtobool value: 'abc'

関連カテゴリー

関連記事