[Python]コマンドライン引数でboolを渡すときの注意点
コマンドライン引数を使う簡単なスクリプトを書くとき、引数としてTrue/Falseを渡して処理を分岐したいなんてことがあったのですが、見事にハマりました。
TL;DR
- Pythonでは、空文字(”)以外の文字列はすべてTrue判定される
- コマンドライン引数は、基本的にstr型で渡されるので、int()でキャストする必要がある
サンプルコード
引数で0 or 1を渡し、False or Trueとして処理を切り替えます。
前提として、Pythonにおいてはintとboolは以下です。
0 : False
1 : True (※正確には0以外のすべて)
# command_line_argv_sample.py import sys def main(argv): flg = bool (argv[ 1 ]) if flg: print ( "Do something." ) else : print ( "Don't do anything." ) if __name__ = = '__main__' : main(sys.argv) |
実行してみると…
$ python command_line_argv_sample.py 0 Do something. |
こうなります。
理由
コマンドライン引数では、値はすべてstr型で渡されるためです。
確認してみます。
... def main(argv): print ( type (argv[ 1 ])) flg = bool (argv[ 1 ]) ... |
$ python command_line_argv_sample.py 0 <class 'str' > Do something. |
対応
intでキャストする
flg = bool ( int (argv[ 1 ])) |
$ python command_line_argv_sample.py 0 Don't do anything. |
うまくいきました。
intでキャストする場合の補足
intはそのままTrue/False判定ができるので、実はbool()でのキャストも不要です。
import sys def main(argv): flg = int (argv[ 1 ]) if flg: print ( "Do something." ) else : print ( "Don't do anything." ) if __name__ = = '__main__' : main(sys.argv) |
strtoboolを使う
True/Falseの文字列をTrue/Falseに変換する標準ライブラリがありました。
import sys from distutils.util import strtobool def main(argv): flg = strtobool(argv[ 1 ]) if flg: print ( "Do something." ) else : print ( "Don't do anything." ) if __name__ = = '__main__' : main(sys.argv) |
$ python command_line_argv_sample.py False Don't do anything. $ python command_line_argv_sample.py True Do something. |
こちらの方がコマンド実行する人に易しいですね。
ディスカッション
コメント一覧
まだ、コメントがありません