pythonでコマンドライン引数を使うサンプル

Pythonの標準ライブラリargparseを使って、コマンドライン引数を扱うメモです。
普通な使い方ですが、サクッと使いたい時のスニペットにどうぞ。

# 課題
pythonスクリプト"hoge.py"に以下の情報を与えつつ実行したい。

- 第一引数にfileのパスを必須で受ける
    - ただしパイプでファイル本体が渡される場合は第一引数不要とする
- オプション引数として--typeオプションで数値を受ける
- オプション引数として--alertを受ける

```python:実行イメージ
# 通常
python hoge.py "data_file_path" --type 3 --alert

# もしくはパイプで情報受ける
cat data.csv | python hoge.py --type 3 --alert
```

# argparse利用

基本的な使い方は非常にシンプル。

```
import argparse

# まずオブジェクト生成
parser = argparse.ArgumentParser()

# 引数設定
parser.add_argument("param")
　　・・・

args = parser.parse_args()

# 参照できる
args.param
```

## 必須の引数と任意の引数

引数設定部分を見ていきます

```python:必須
parser.add_argument("file")
parser.add_argument("input", help="please set me", type=str)
```
add_argumentにそのまま引数名を指定すると、必須の引数として扱われます。
また、helpを指定しておくと、`python hoge.py -h`とした時に説明文が表示される親切設計です。
typeにより型を指定することもできます。設定できることはまだまだ多いので知りたい場合は参考からどうぞ。

次にオプショナル引数を指定したい場合は名前の先頭に"--"を指定するだけです。

```python:任意
parser.add_argument("--option", help="optional")
parser.add_argument("--flag", help="optional", action="store_true")
```
この例の場合、--optionが指定された場合、後に情報をとることを期待します。

```python:オプションあり
python hoge.py --option "hogehoge"
↓
args.option # hogehoge
```
```python:オプション省略
python hoge.py
↓
args.option # Noneが設定されるので
#if args.option:
#　　　　〜〜
#　　　　という使い方でエラーが起きない
```

フラグのように使いたい場合は`--flag`の例のように、`action`に`store_true`か`store_false`を設定します。
これにより`--flag`が指定された場合は`true/false`が設定されるようになります。

```python:オプションあり
python hoge.py --flag
↓
args.flag # true
```
```python:オプション省略
python hoge.py
↓
args.flag # false
```

# ついでにパイプ対応

標準入力から情報が渡ってきたかどうかを判定して、add_argumentを追加することで必須引数の制御をして見ます。

```python:is_a_tty
# 標準入力で渡されていなければfileを必須とする
if sys.stdin.isatty():
    parser.add_argument("file")
# 共通
parser.add_argument("--option", type=int)
```

`sys.stdin.isatty()`で判定して加えるかどうかを切り替えるだけで問題なしでした。

#完成

```python:課題
import sys
import argparse

def get_args():
    # 準備
    parser = argparse.ArgumentParser()

    # 標準入力以外の場合
    if sys.stdin.isatty():
        parser.add_argument("file", help="please set me", type=str)

    parser.add_argument("--type", type=int)
    parser.add_argument("--alert", help="optional", action="store_true")
    
    # 結果を受ける
    args = parser.parse_args()
    
    return(args)

def main():
    args = get_args()

    if hasattr(args, 'file'):
        print(args.file)
    print(args.type)
    print(args.alert)
    
    if args.alert:
        None;# alertが設定されている場合

if __name__ == '__main__':
    main()
```

ヘルプを見ると

```sh:ヘルプ
$ python hoge.py -h
usage: hoge.py [-h] [--type TYPE] [--alert] file

positional arguments:
  file         please set me

optional arguments:
  -h, --help   show this help message and exit
  --type TYPE
  --alert      optional
```

```sh:実行
# これはOK
$ python hoge.py "file" --alert --type 3
file
3
True

$ echo "hoge" | python hoge.py 
None
False

# これはNG
$ python hoge.py 
usage: hoge.py [-h] [--type TYPE] [--alert] file
hoge.py: error: the following arguments are required: file
```

# 参考

- [Argparse チュートリアル](https://docs.python.jp/3/howto/argparse.html)
- [argparse — コマンドラインオプション、引数、サブコマンドのパーサー](https://docs.python.jp/3/library/argparse.html)
- [Python argparseの使い方](https://qiita.com/dodo5522/items/6ec2b6d83287add6c185)