pythonでCliアプリケーションを作成する際、コマンドライン引数を名前付きで与えたくていろいろ調べたところ、Fireというパッケージを発見しました。
sys.argvとかargparseとかclickとかありましたが、もっともすっきりかけるのがFireかと思います。
早速実装
とりあえずベースはこんな感じで
def main() -> None:
print("mainです")
if __name__ == "__main__":
main()
実行
python test1.py
結果
mainです
Fireを使ってみる
import fire
def main() -> None:
print("mainです")
if __name__ == "__main__":
fire.Fire(main)
実行
python test2.py
結果
mainです
実行は無事できました。
引数を与えてみる
import fire
def main(message: str) -> None:
print(message)
print(type(message))
if __name__ == "__main__":
fire.Fire(main)
messageという名前で文字列を受け取り、その文字列と型をprintするようにしてみました。
まずはこれまで同様、引数なしで実行してみましょう。
python test3.py
結果
ERROR: The function received no value for the required argument: message
Usage: test3.py MESSAGE
For detailed information on this command, run:
test3.py --help
引数が不足している旨のメッセージが表示されました。
--help
で詳細が見れると書いてありますね。見てみましょう。
python test3.py --help
結果
NAME
test3.py
SYNOPSIS
test3.py MESSAGE
POSITIONAL ARGUMENTS
MESSAGE
Type: str
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS
vimっぽい状態で上記内容が表示されました。q
で抜けられます。
ファイル名と概要、引数の名称と型、位置引数にフラグ?を使用することもできます的なメッセージが表示されてます。
ちなみにこれは-h
の短縮形でも表示されました。
引数を与えて実行してみます。
python test3.py --message=こんにちは
こんにちは
<class 'str'>
成功です!
Optional Argumentsの追加
import fire
def main(message: str, suuji: int = 0) -> None:
print(message)
print(suuji)
if __name__ == "__main__":
fire.Fire(main)
suujiというint型のデフォルト引数を追加してみました。
helpを見てみます。
python test4.py -h
NAME
test4.py
SYNOPSIS
test4.py MESSAGE <flags>
POSITIONAL ARGUMENTS
MESSAGE
Type: str
FLAGS
--suuji=SUUJI
Type: int
Default: 0
NOTES
You can also use flags syntax for POSITIONAL ARGUMENTS
FLAGSとしてsuujiが追加されました。NOTESに書いてあるflag syntaxというやつになったということでしょうか?
とりあえず実行してみます。
python test3.py --message=こんにちは
結果
こんにちは
10
思った通りには実行されてますね。
名前付きでの実行を強制する
helpで見たときにPOSITIONAL ARGUMENTS
として定義されている通り、これは位置引数としても定義されています。
python test4.py こんにちは 1
こんにちは
1
折角なので名前付き引数であることを強制してみます。
Pythonで関数定義をする際、*
より後ろは名前付き引数であることを強制できるのでそれでやってみましょう。
import fire
def main(*, message: str, suuji: int = 0) -> None:
print(message)
print(suuji)
if __name__ == "__main__":
fire.Fire(main)
helpを見てみます。
python test5.py -h
結果
NAME
test5.py
SYNOPSIS
test5.py <flags>
FLAGS
--message=MESSAGE (required)
Type: str
--suuji=SUUJI
Type: int
両方FLAGS
のほうに行きましたね。
先ほどの位置引数指定バージョンで実行してみます。
ERROR: Missing required flags: {'message'}
Usage: test5.py <flags>
optional flags: --message
required flags: --suuji
For detailed information on this command, run:
test5.py --help
ちゃんとエラーとなりました。
名前付きなら無事実行できます。
python test5.py --message=こんにちは --suuji=1
こんにちは
1
まとめ
argparse使ってたことがありますが、それと比較するとめちゃくちゃ楽ですね。
ちょっとしたCLIアプリケーションを作るときPythonは便利なので、これでできることが広がります。