The article on Python-fire was popped up a bit, so I pretended to see it.
ʻArgparse` is good, right?
Consider a CLI with a simple "return the result of adding two accepted arguments" subcommand ʻadd.
calc-1.py is left to
python-fire, and
calc-2.py is a replacement of it with ʻ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))
I feel that the readability will be improved tremendously. If you write a little CLI processing, the argument parser part occupies a considerable proportion of the code, so it may be appreciated if this is eliminated.
It seems that (subcommand) ---- hep
will take argument information.
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
File information is a little intrusive, but it seems to play a role as Usage.
If you call it without thinking, calc-1.py
is obviously slower.
$ 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
If you simply compare it only once, it looks like this. There seems to be a difference of about 0.5 sec.
So, I tried to make such a loop.
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
I tried to repeat it a few times, but on average it seems that it takes about 0.4 to 0.5 seconds extra. Considering that the main processing of the sample code is too simple, it seems that there are enough cases that it will be an error in actual operation.
python-fire
nice
Recommended Posts