【fire】楽チン!コマンドライン引数の自動設定ライブラリのテスト
コマンドライン引数を簡単に設定してくれるというPython用ライブラリfire
を試します。
$ pip install fire
など環境に合わせて先にインストールしておきます。
【実行環境】
- Android
- Termux
- Python3.9
コマンドライン引数をプログラムに渡したいとき、通常はsys.argv
やargparse()
を使いますが、fire
を使うともっと簡単にできるらしい。本当かしら?
Pythonスクリプトを準備
引数を受けると、引数・引数の型・引数の要素数を返すプログラムを準備しました。コマンドライン引数については何の考慮もなしです。
testfire.py
# ライブラリのインポート import fire # 関数の定義 def test(x): return x,type(x),len(x) # ファイヤー! fire.Fire(test)
電流爆破を起こすプログラムです(ウソ
定義した関数やクラスを、Fire()
に渡すたけでコマンドライン引数が自動的に使えるようになるのだと。
- コマンドライン引数を関数に渡すような文は一行も書いてません。
- インポートしたfireのFireクラスにそのまま関数名を渡しただけ
実行したら「引数・引数の型・引数の要素数」が表示される筈。
こんなので本当に動くのかいな?
実行
してみます。
$ python firetest.py wwwwww ('wwwwww', <class 'str'>, 6)
動くねぇ。
- 型 :
str型
- 要素数 : 6
今度は引数を2つ渡してみよう
$ python firetest.py hello world 666 ERROR: Unable to index into component with argument: world Usage: firetest.py hellow <command|index> available commands: count | index available indexes: 0, 1, 2 For detailed information on this command, run: firetest.py hellow --help
エラーと表示された。詳細はヘルプでと。
ヘルプのオプション引数を見てみる
自動でヘルプのオプションを用意してくれている。親切。
通常ヘルプは「--help」か「-h」で出る。
$ python firetest.py --help NAME firetest.py SYNOPSIS firetest.py X POSITIONAL ARGUMENTS X NOTES You can also use flags syntax for POSITIONAL ARGUMENTS
スクリプトに「x」と書いていたので1つしか受けないみたい。
可変長の引数に書き換え
てみようか。
firetest.py
# ライブラリのインポート import fire # 関数の定義 def test(*x): #←「*」追加で可変長に return x, type(x), len(x) # ファイヤー! fire.Fire(test)
実行します。
$ python firetest.py hello world 666 (('hellow', 'world', 666), <class 'tuple'>, 3)
行けたね。タプル型。ファイル自身は含まず。
ヘルプを見てみると、
$ python firetest.py --help NAME firetest.py SYNOPSIS firetest.py [X]... POSITIONAL ARGUMENTS X
自動的にヘルプも作られる。
関数の引数を「*
」で可変長にしたのでSYNOPSIS
の部分がX
から[X]
に変わった。器がでかくなった。
CLIツールにして実行を確かめる
自作Pythonスクリプトをコマンド1発で動かせるCLIツールにして、動くかどうか確認してみる。
まずはCLIツール用にスクリプトを書き替えます。実行部分を関数化します。
firetest.py
import fire def test(*x): return x,type(x),len(x) # 実行部分を関数化した def main(): fire.Fire(test) if __name__=='__main__': main()
CLIツール化の時に作るsetup.py
で呼び出す関数名を指定する必要があるので、main()
で関数化しました。
そして、setup.py
を用意します。
from setuptools import setup setup( name="fire_test", #パッケージ名 version="0.0.1", #パッケージバージョン install_requires=["fire"], #必要なライブラリ entry_points={ "console_scripts": [ "firetest = firetest:main" #コマンド名=呼び出すファイル名:関数名 ] } )
フォルダを作って、上の2つのファイルをそこに閉じ込めます。
$ mkdir TEST ← フォルダ作成 $ mv firetest.py setup.py TEST/ ←ファイルを移動 $ cd TEST ←カレントディレクトリを移動 $ ls ←ディレクトリ内容を確認 firetest.py setup.py $ tree ←ディレクトリ構成表示 . ├── firetest.py └── setup.py 0 directories, 2 files
準備ができたのでCLIツール化します。
$ python setup.py develop または $ pip install -e . Obtaining file:///なんとか/firetest Requirement already satisfied: fire in /なんとか/usr/lib/python3.9/site-packages (from fire-test==0.0.1) (0.4.0) Requirement already satisfied: termcolor in /なんとか/usr/lib/python3.9/site-packages (from fire->fire-test==0.0.1) (1.1.0) Requirement already satisfied: six in /なんとか/usr/lib/python3.9/site-packages (from fire->fire-test==0.0.1) (1.15.0) Installing collected packages: fire-test Running setup.py develop for fire-test Successfully installed fire-test
pip list
コマンドで自作スクリプトがインストールされたか確認できます。また、カレントディレクトリにfire_test.egg-info/
が自動作成されています。
CLIツールの実行確認
できたコマンドを実行します。setup.py
の"console_scripts":
で指定したコマンド名を使えるようになっています。
コマンドだけ入力してみる。
$ firetest ((), <class 'tuple'>, 0)
ヘルプを表示。
$ firetest --help NAME firetest SYNOPSIS firetest [X]... POSITIONAL ARGUMENTS X
コマンドライン引数を1つ与える。
$ firetest ファイヤー (('ファイヤー',), <class 'tuple'>, 1)
次は2つ。
$ firetest なんでん かんでん (('なんでん', 'かんでん'), <class 'tuple'>, 2)
ちゃんと動くね。🆗👌
CLIツールのアンインストール
- 呼び出すファイル(firetest.py)だけを書き換える場合はアンインストールせずとも変更が反映されますが、
- setup.py側のコマンド名や呼び出すファイル名、関数名を内容変更する場合は一旦アンインストールする必要がある。(アップデートで行けるかも。未確認)
setup.py
を置いたディレクトリ(この場合TEST)で以下のコマンド。
$ pip uninstall fire-test または $ python setup.py develop -u なんとかかんとか Successfully uninstalled fire-test
と出ればアンインストール完了。
カレントディレクトリに自動作成されたフォルダはアンインストール後は不要なので、削除するなら
$ rm -rf fire_test.egg-info __pychash__
これで中身のファイルごと削除される。
【注意】
実行してはいけないLinuxコマンド(3) Windows 10 WSLで『rm -rf /』を実行 | TECH+
改造
次のように改造して動くか確認する。
firetest.py
import fire def test(*x): return x,type(x),len(x) fire.Fire(test)
main()を削除した。
setup.py
from setuptools import setup setup( name="fire_test", version="0.0.1", install_requires=["fire"], entry_points={ "console_scripts": [ "firetest = firetest:test" #←mainをtestに変更 ] } )
呼び出す関数をmain()からtest()に変更した。setup.pyを書き換えたので一旦アンインストールした。
先ほどのインストール手順で再インストールし直し実行確認してみる。
$ firetest ggg hhh (('ggg', 'hhh'), <class 'tuple'>, 2) ((), <class 'tuple'>, 0)
二度実行されています。
firetest.py
のfire.Fire(test)
をコメントアウトすると実行結果は((), <class 'tuple'>, 0)
だけが表示される。
またアンインストールし、次は複数の関数でできるか確認します。
複数の関数で確認
ここからはCLIツールのコマンド化はしません。firetest.pyのみを使う。
次のように書き換える。
import fire def test(*x): return x,type(x),len(x) def test2_rev(*y): return [i[::-1] for i in y] # 実行 fire.Fire(test) fire.Fire(test2_rev)
関数を2つ作って、fire.Fire()で2つ実行させるようにしました。
$ python firetest.py 上から読んでも 下から読んでも やまもとや (('上から読んでも', '下から読んでも', 'やまもとやま'), <class 'tuple'>, 3) もでん読らか上 もでん読らか下 まやともまや
ヘルプを表示
$ python firetest.py --help NAME firetest.py SYNOPSIS firetest.py [X]... POSITIONAL ARGUMENTS X
1つ目の関数しか出ていない。
まるごと読み込む
fire.Fire()
に何も渡さなければ丸ごと読み込まれるらしい。大泥棒か
firetest.py
import fire def test(*x): return x,type(x),len(x) def test2_rev(*y): return [i[::-1] for i in y] fire.Fire() #←何も書かない
ヘルプを見てみる。
$ python firetest.py --help NAME firetest.py SYNOPSIS firetest.py GROUP | COMMAND GROUPS GROUP is one of the following: fire The Python Fire module. COMMANDS COMMAND is one of the following: test test2_rev
変数の表示とかがされなくなったな。どこ行った。
コマンドライン引数を与える実行してみる。
$ python firetest.py hello ERROR: Cannot find key: hello Usage: firetest.py <group|command> available groups: fire available commands: test | test2_rev For detailed information on this command, run: firetest.py --help
おっと、普通に実行出来なくなった。上のヘルプ表示の「Usage」に使い方が、「available commands:」に2つ関数名が載っている。
使い方のように引数で渡すと実行できるようだ。
$ python firetest.py test2_rev hello olleh
オレッ!
他のでも
$ python firetest.py test2_rev 吾輩は猫である トンネルを抜けるとそこは雪国だった ここが何処だかとんと見当が付かぬ るあで猫は輩吾 たっだ国雪はこそとるけ抜をルネント ぬか付が当見とんとかだ処何がここ
ぬか漬けがどうのこうの。イケるねぇ(by 中尾彬
参考リンク
こちらにはclassを使う場合など例文がいくつか載っている。
おわりに
ファイルの最後の実行部分に「fire.Fire()」を付けるだけなので相当楽チンかも。
以上です。