Pythonのargparseでブール値を扱うときは注意が必要
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'>
コマンドライン引数100がintとして読み込まれる。
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()のtypeにboolを指定してはいけない
注意が必要なのがbool。intやfloatなどのようにadd_argument()の引数typeにboolを指定すると想定外の結果となる。
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を返す。
以下のオブジェクトは偽と判定される。
- 偽であると定義されている定数:
NoneとFalse- 数値型におけるゼロ:
0,0.0,0j,Decimal(0),Fraction(0, 1)- 空のシーケンスまたはコレクション:
'',(),[],{},set(),range(0)組み込み型 - 真理値判定 — Python 3.13.3 ドキュメント
それ以外のオブジェクトはすべて真と判定される。したがって、'True'でも'False'でも、空ではない文字列をbool()に渡すとすべてTrueが返される。空文字列のみがFalseとなる。
print(bool('True'))
print(bool('False'))
print(bool('abc'))
# True
# True
# True
print(bool(''))
# False
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'の、それぞれTrueとFalseを格納する特別版になります。加えて、これらはそれぞれデフォルト値を順にFalseとTrueにします。 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 ドキュメント
以前は整数intの1または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))
trueやfalseなどの文字列の引数を真偽の値として読み込むことができる。
$ 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'