Python-fireの記事とかがはてぶとかでちょこちょこ上がったので、素振りして見たメモ。
動作確認してた環境
- Macbook Pro 13inch Early 2015
- Python 3.6.0 from pyenv
自分でREADMEを読んでみただけの時の感想
argparse
でよくね?
実際に比較する
単純な「受け付けた引数2個を足した結果をかえす」サブコマンドadd
を持つCLIについて考えてみました。
calc-1.py
はpython-fire
に任せたもの、calc-2.py
はそれをargparse
に置き換え直したものです。
calc-1.py
import fire
class Calcurator(object):
def add(self, first, second):
return int(first) + int(second)
if __name__ == '__main__':
fire.Fire(Calcurator)
calc-2.py
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('mode')
parser.add_argument('first')
parser.add_argument('second')
class Calcurator(object):
def add(self, first, second):
return int(first) + int(second)
if __name__ == '__main__':
args = parser.parse_args()
cli = Calcurator()
print(getattr(cli, args.mode)(args.first, args.second))
ものすごく、可読性がよくなる気がする。
ちょこちょこCLIな処理を書くと、コードの結構な割合をargument parserの部分が占めるので、これがなくなると割とありがたいかもしれない。
ヘルプ表示的なもの
(subcommand) -- --hep
で引数情報とかを取ってくれるらしい。
calc-1.py
$ python calc-1.py add -- --help
Type: method
String form: <bound method Calcurator.add of <__main__.Calcurator object at 0x1036f8fd0>>
File: ~/Dropbox (nijibox)/Applications/act/calc-1.py
Line: 5
Usage: calc-1.py add FIRST SECOND
calc-1.py add --first FIRST --second SECOND
calc-2.py
$ python calc-2.py -h
usage: calc-2.py [-h] mode first second
positional arguments:
mode
first
second
optional arguments:
-h, --help show this help message and exit
ファイル情報とかはちょっと邪魔だけど、Usageとしての役割は果たしている模様。
処理時間を比較する
何も考えずに呼び出しをすると、あからさまにcalc-1.py
の方が処理が遅くなる。
$ time python calc-1.py add 12345 67890
80235
python calc-1.py add 12345 67890 0.60s user 0.29s system 30% cpu 2.945 total
$ time python calc-2.py add 12345 67890
80235
python calc-2.py add 12345 67890 0.07s user 0.07s system 77% cpu 0.179 total
単純に一回だけ比較するとこんな感じ。0.5secぐらいの差がある模様。
で、こんなループをさせてみた。
loop.py
import sys
import subprocess
script = sys.argv[1]
count = int(sys.argv[2])
for _ in range(count):
proc = subprocess.Popen('python {} add 12345 67890'.format(script).split(), stdout=None)
proc.communicate()
loop.py
$ time python loop.py calc-1.py 10 > /dev/null
python loop.py calc-1.py 10 > /dev/null 4.29s user 1.20s system 97% cpu 5.651 total
$ time python loop.py calc-2.py 10 > /dev/null
python loop.py calc-2.py 10 > /dev/null 0.40s user 0.17s system 93% cpu 0.614 total
$ time python loop.py calc-1.py 100 > /dev/null
python loop.py calc-1.py 100 > /dev/null 45.53s user 12.45s system 88% cpu 1:05.32 total
$ time python loop.py calc-2.py 100 > /dev/null
python loop.py calc-2.py 100 > /dev/null 3.39s user 1.06s system 94% cpu 4.731 total
雑に回数重ねてみたけど、平均するとやっぱり0.4〜0.5秒ぐらいの時間が余計にかかっている感じ。
サンプルコードはメイン処理が余りにもシンプルな処理なことを考慮すると、実運用だと誤差になってくるケースは十分ありそう。
軽く検証した後の感想
python-fire
いいな