追記しました。argparseのテストで気をつけるべきこと。
こちらに移転、更新しました。
スクリプトの引数仕様
とあるスクリプトの引数の仕様を下記のようにしたい。
- srcディレクトリパスの指定は必須
- dstディレクトリパスの指定は必須ではない
- 対象とするファイルの拡張子を複数指定したい
- debug用のprint文は普段はstdoutに出したくない
といった仕様をargparseを使って実装し、--helpして表示した結果が下記。
次の章からこの実装方法を順を追ってメモしておく。
$ ./photosort.py --help
usage: photosort.py [-h] [-d [PATH_ROOT_DST]]
[-e SORT_FILES_EXTENTIONS [SORT_FILES_EXTENTIONS ...]]
[--debug]
path_root_src
This script is ...
positional arguments:
path_root_src Directory path where your taken photo files are
located.
optional arguments:
-h, --help show this help message and exit
-d [PATH_ROOT_DST], --path-root-dst [PATH_ROOT_DST]
Directory path where you want to create date folder
and locate photo files. (default: same as source
directory)
-e SORT_FILES_EXTENTIONS [SORT_FILES_EXTENTIONS ...], --sort-files-extentions SORT_FILES_EXTENTIONS [SORT_FILES_EXTENTIONS ...]
Extentions of file which you want to sort. (default:
jpg)
--debug debug mode if this flag is set (default: False)
まずは初期化
description以外はデフォルトのままでほとんどの用途に対しては問題ないと思う。
add_help(-h/–help オプションをパーサーに追加する)等、通常使うであろうパラメータは予め有効になっている。
parser = argparse.ArgumentParser(description='This script is ...')
引数の追加
その1
デフォルトの設定のままでよいパラメータもあえて指定している。(デフォルトが何なのか、ヘルプを見ないと分からないというのも面倒なので)
srcディレクトリパスの指定は必須
add_argumentの第一引数に、-や--を付けない名前'path_root_src'を、nargsにNoneを指定する。
これにより、-や--付オプション以外の引数がスクリプトに指定されていない場合はtoo few argument
エラーとなる。
もしnargsを'?'にして、defaultやconst等のパラメータと組み合わせて指定した場合は、エラーになることなくスクリプトを実行できることになる。
parser.add_argument('path_root_src', \
action='store', \
nargs=None, \
const=None, \
default=None, \
type=str, \
choices=None, \
help='Directory path where your taken photo files are located.', \
metavar=None)
ここで指定した第一引数の文字列'path_root_src'は、最後の仕上げでコールするargs = parser.parse_args()
が返すNamespaceオブジェクトの属性名として使用される。
つまり、下記のように実行した場合、args.path_root_src
に"/Users/test/Pictures"が格納される。
$ ./photosort.py /Users/test/Pictures
その2
dstディレクトリパスの指定は必須ではない
add_argumentの第一引数に2種類のオプション文字列を、nargsに'?'を指定する。
これにより、可能なら1つの引数がコマンドラインから取られ、args = parser.parse_args()
が返すNamespaceオブジェクトの属性名'path_root_dst'として使用され、引数の値はその属性にセットされる。
オプション引数そのものが存在しない(-d自体が指定されない)場合はdefaultの値が渡される。
オプション引数が指定され、その後にコマンドライン引数が無い場合はconstの値が渡される。
下記の例の場合、どちらもNoneなのであまり意味はないが…。
parser.add_argument('-d', '--path-root-dst', \
action='store', \
nargs='?', \
const=None, \
default=None, \
type=str, \
choices=None, \
help='Directory path where you want to create date folder and locate photo files. (default: same as source directory)', \
metavar=None)
その3
対象とするファイルの拡張子を複数指定したい
add_argumentの第一引数に2種類のオプション文字列を、nargsに'+'を指定する。
これにより、最低でも1つのコマンドライン引数が必要となり、条件を満たさない場合はtoo few argument
エラーとなる。
ただし、上記エラーになるのは-eが指定されているのにコマンドライン引数が指定されていない場合のみ。
-e自体が指定されていない場合は、defaultに指定した['jpg']
が使用され、エラーとはならない。
parser.add_argument('-e', '--sort-files-extentions', \
action='store', \
nargs='+', \
const=None, \
default=['jpg'], \
type=str, \
choices=None, \
help='Extentions of file which you want to sort. (default: jpg)', \
metavar=None)
その4
debug用のprint文は普段はstdoutに出したくない
あるオプション引数が指定された場合、単純にTrueかFalseを持っていて欲しい場合、actionに'store_true'や'store_false'を指定することで実現できる。
このスクリプトが--debug付きで実行された場合は、最後の仕上げでコールするargs = parser.parse_args()
が返すNamespaceオブジェクトの属性名args.debug
にTrueが格納されることになる。
parser.add_argument('--debug', \
action='store_true', \
help='debug mode if this flag is set (default: False)')
最後の仕上げ
これまでに指定した引数をオブジェクトに変換し、Namespaceオブジェクトの属性に代入して、そのオブジェクトを返してもらう。
デフォルトで、引数文字列はsys.argvから取られるので、ここで特に引数に何か指定する必要は無い。
args = parser.parse_args()
実行結果
add_argumentで指定した名前の属性が、parse_argsが返すNamespaceオブジェクトに追加されていることが分かる。
(Pdb) b 112
Breakpoint 1 at /Users/dodo5522/Development/manage_media_data/photosort.py:112
(Pdb) c
> /Users/dodo5522/Development/manage_media_data/photosort.py(112)<module>()
-> args = parser.parse_args()
(Pdb) n
(Pdb) dir(args)
['__class__', '__contains__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs', 'debug', 'path_root_dst', 'path_root_src', 'sort_files_extentions']
(Pdb) args.debug
(Pdb) print args.debug
False
(Pdb) print args.path_root_dst
/Users/dodo5522/Public
(Pdb) print args.path_root_src
/Users/dodo5522/Pictures
(Pdb) print args.sort_files_extentions
['jpg', 'png', 'mov']
(Pdb)