Pythonのdocopt使い方メモ

## はじめに
Pythonのdocopt（引数の定義と解釈を行うライブラリ）の使い方・注意点メモです。
docoptは超便利ですが、docoptが超便利！っていう話は特に書きません。

## 使い方

`__doc__`にUsageとOptionsを定義しておき、`docopt(__doc__)`として参照します。
`args = docopt(__doc__)`とすれば`args`は代替引数やオプションをキーとした辞書になります。

argsのkeyとvalueを全て表示するテストスクリプトで試してみます。

```py
"""Overview:
  サブコマンド・オプション・引数をdocoptで受け、keyとvalueを全表示する

Usage:
  docopt_test xx1 <yy1>
  docopt_test [-a] [-b|--bbb] [-c...]
              [-d|--ddd <D>] [-e <E>] [<z>...]
  docopt_test xx2 <yy2>  # サブコマンドをこの位置に書くのはダメな例。後述。

Options:
  xx1          : サブコマンド    → 有無を示すTrue/False
  <yy1>        : 必須引数        → 引数文字列のリスト
  xx2          : サブコマンド    → 有無を示すTrue/False
  <yy2>        : 必須引数        → 引数文字列のリスト
  -a           : 任意オプション(引数なし)  → 有無を示すTrue/False
  -b --bbb     : 任意オプション(引数なし)  → 有無を示すTrue/False
  -c...        : 任意オプション(引数なし)  → 指定回数を示す数値
  -d --ddd <D> : 任意オプション(引数あり)  → 引数文字列のリスト
  -e <E>       : 任意オプション(引数あり)  → 引数文字列のリスト
  <z>          : 任意引数                  → 引数文字列のリスト
"""

from docopt import docopt

if __name__ == '__main__':
    args = docopt(__doc__)
    print("  {0:<20}{1:<20}{2:<20}".format("kye", "value", "type"))
    print("  {0:-<60}".format(""))
    for k,v in args.items():
        print("  {0:<20}{1:<20}{2:<20}".format(str(k), str(v), str(type(v))))
```

実行結果は以下のようになりました。
リスト型なので順番は保証されません（＝実行するたびに変わります）。
今回は見やすいように順序を定義順に揃えています。

```
$ python docopt_test.py
  kye                 value               type
  ------------------------------------------------------------
  xx1                 False               <class 'bool'>
  <yy1>               None                <class 'NoneType'>
  -a                  False               <class 'bool'>
  --bbb               False               <class 'bool'>
  -c                  0                   <class 'int'>
  --ddd               []                  <class 'list'>
  -e                  None                <class 'NoneType'>
  <z>                 []                  <class 'list'>
  xx2                 False               <class 'bool'>
  <yy2>               None                <class 'NoneType'>
```

引数を何も指定していないので値が全て `None`、`[]`、`False` になっています。

では次に`-cc -d DDD GGG -a`を指定してみます。
わかりやすいよう、変化した部分に★マークをつけています。

```
$ python docopt_test.py -cc -d DDD GGG -a HHH
  kye                 value               type
  ------------------------------------------------------------
  xx1                 False               <class 'bool'>
  <yy1>               None                <class 'NoneType'>
  -a               ★ True                <class 'bool'>
  --bbb               False               <class 'bool'>
  -c               ★ 2                   <class 'int'>
  --ddd            ★ ['DDD']             <class 'list'>
  -e                  None                <class 'NoneType'>
  <z>              ★ ['GGG', 'HHH']      <class 'list'>
  <yy2>               None                <class 'NoneType'>
  xx2                 False               <class 'bool'>
```

`-c`の指定回数`2`、`-d|--ddd`の引数`DDD`、位置引数`GGG`と`HHH`、`-a`指定が入ってきたのがわかると思います。

また定義外のオプションを指定するなど、解釈できない場合はUsageが表示されます。

```
$ python docopt_test.py -A
Usage:
  docopt_test xx1 <yy1>
  docopt_test [-a] [-b|--bbb] [-c...]
              [-d|--ddd <D>] [-e <E>] [<z>...]
  docopt_test xx2 <yy2>
```

## 注意点：Usageは定義順にチェックされ、最初に一致したもので解釈される

端的に表現するのが難しくてこんな章タイトルにしてしまいました。
実例を見ていただきましょう。サブコマンド`xx1`を指定します。
これは本当は必須引数が必要なので、サブコマンドだけを指定した場合エラーになりそうです。

と思いましたがエラーになりませんでした。
任意引数`<z>`として`xx1`という文字列が渡されたことになっています。
そう解釈すれば一致する（解釈できる）からでしょう。

```
$ python docopt_test.py xx1
  kye                 value               type
  ------------------------------------------------------------
  xx1              ☆ False               <class 'bool'>
  <yy1>            ☆ None                <class 'NoneType'>
  -a                  False               <class 'bool'>
  --bbb               False               <class 'bool'>
  -c                  0                   <class 'int'>
  --ddd               []                  <class 'list'>
  -e                  None                <class 'NoneType'>
  <z>              ★ ['xx1']             <class 'list'>
  xx2                 False               <class 'bool'>
  <yy2>               None                <class 'NoneType'>
```


`xx1 foo`を与えてみると、`xx1`が`True`、`<yy1>`が`foo`になります。

```
$ python docopt_test.py xx1 foo
  kye                 value               type
  ------------------------------------------------------------
  xx1              ★ True                <class 'bool'>
  <yy1>            ★ foo                 <class 'str'>
  -a                  False               <class 'bool'>
  --bbb               False               <class 'bool'>
  -c                  0                   <class 'int'>
  --ddd               []                  <class 'list'>
  -e                  None                <class 'NoneType'>
  <z>                 []                  <class 'list'>
  xx2                 False               <class 'bool'>
  <yy2>               None                <class 'NoneType'>
```

この調子で`xx2 foo`を与えてみると、全て`<z>`と解釈されてしまいます。
`docopt_test xx2 <yy2>`よりも先に` docopt_test [<z>...]`が定義されているためでしょう。

```
$ python docopt_test.py xx2 foo
  kye                 value               type
  ------------------------------------------------------------
  xx1                 False               <class 'bool'>
  <yy1>               None                <class 'NoneType'>
  -a                  False               <class 'bool'>
  --bbb               False               <class 'bool'>
  -c                  0                   <class 'int'>
  --ddd               []                  <class 'list'>
  -e                  None                <class 'NoneType'>
  <z>              ★ ['xx2', 'foo']      <class 'list'>
  xx2              ☆ False               <class 'bool'>
  <yy2>            ☆ None                <class 'NoneType'>
```


そういった機会があるかどうかわかりませんが、
もしも、**全てのパターンが一致してしまうようなUsageを定義するなら、後ろにもっていく**ようにしましょう
上記の例ではサブコマンド`xx2`を指定することができません。