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'