0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Fireを使ってPythonスクリプトで引数を受け取る

Last updated at Posted at 2021-05-23

pythonでCliアプリケーションを作成する際、コマンドライン引数を名前付きで与えたくていろいろ調べたところ、Fireというパッケージを発見しました。
sys.argvとかargparseとかclickとかありましたが、もっともすっきりかけるのがFireかと思います。

早速実装

とりあえずベースはこんな感じで

test1.py
def main() -> None:
    print("mainです")


if __name__ == "__main__":
    main()

実行

python test1.py

結果

mainです

Fireを使ってみる

test2.py
import fire


def main() -> None:
    print("mainです")


if __name__ == "__main__":
    fire.Fire(main)

実行

python test2.py

結果

mainです

実行は無事できました。

引数を与えてみる

test3.py
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の追加

test4.py
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で関数定義をする際、*より後ろは名前付き引数であることを強制できるのでそれでやってみましょう。

test5.py
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は便利なので、これでできることが広がります。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?