Python Fireについて¶
Python Fireは、サードパーティのライブラリーです。pip install fire
でインストールすると使えます。
Python Fireを使うと、「コマンドラインからオブジェクトを自由に操作」できるようになります。 そのために必要なことは、オブジェクトをFireに登録することだけです。簡単に使い始められるというのがメリットです。
オブジェクトには、関数やクラスも含めて任意のオブジェクトが扱えます。 ドキュメントは、The Python Fire Guide です。
以下に主な使用方法を紹介します。
関数のコマンドライン化¶
Python Fireを使うには、from fire import Fire
して、Fire(コマンドラインで使用したい関数)
とします。つまり「使用したい関数をFire
に登録」だけです。
下記をsample.py
というファイル名で作成してください(以降も同名のファイルを扱います)。
from random import choice
from fire import Fire
Fire(choice)
python sample.py [1,2,3]
を実行すると、1, 2, 3
のいずれかが出力されます。これは、Pythonでprint(choice([1, 2, 3]))
を実行するのと同じになります。
また、python sample.py [大吉,吉,小吉]
を実行すると、大吉, 吉, 小吉
のいずれかが出力されます。
python sample.py ["大吉","吉","小吉"]
としなくても「大吉」などを文字列と認識します。python sample.py [大吉, 吉, 小吉]
のようにスペースを入れるとエラーになるので注意してください。
Fire(choice)
とするだけで、簡単に、おみくじとして使うことができます。
ヘルプの表示¶
以下のいずれの方法でもヘルプを表示できます。
python sample.py --help
python sample.py -- --help
python sample.py -h
python sample.py -- -h
このように、Python Fireでは、自動的に「ヘルプを表示する機能」が使えます。
--help
あるいは-h
をつけることでヘルプが表示されます。「Choose a random element from a non-empty sequence.」という説明が出てきます。
--
を書くことによって、以降の引数が、sample.py
に対してはなくFire
に対するものになります。今回は、「--help
や-h
」がsample.py
の引数でないことが自明なので、--
は不要になっています。
また、自作の関数を登録して、詳しいヘルプを出したい場合は、その関数にdocstringを記述してください。
複数の関数のコマンドライン化¶
複数の関数を使えるようにするには、Fire
に辞書を渡します。
辞書のキーにコマンド名を、値に関数を指定します。
たとえば、Fire({"min": min, "max": max})
とすることで、min
とmax
の2つのコマンドが使えます。
python sample.py -h
またはpython sample.py
でヘルプを表示します。
ヘルプを見ると、python sample.py コマンド
のように使えて、コマンドとしてmin
とmax
が選べることがわかります。
python sample.py min 1 -2 3
を実行すると、min(1, -2, 3)
を計算して-2
と表示されます。python sample.py max 1 -2 3
を実行すると、max(1, -2, 3)
を計算して3
と表示されます。
引数にリストを指定できます。
python sample.py min [1,-2,3]
を実行すると、min([1, -2, 3])
を計算して-2
と表示されます。
引数に文字列を指定できます。
python sample.py min cat
を実行すると、min("cat")
を計算してa
と表示されます。min("cat")
は、min(["c", "a", "t"])
と同じです。
辞書のキーがコマンドになります。
もし、Fire({"MIN": min, "MAX": max})
としていれば、python sample.py MIN 1 -2 3
のように使います。
辞書の要素数は、3つ以上でも可能です。
もし、Fire({"min": min, "max": max, "sum": sum})
としていれば、python sample.py sum [1,-2,3]
を実行すると、sum([1, -2, 3])
を計算して2と表示されます。
引数の文字列はPythonのコードのように評価され、適切な型のオブジェクトになって実行されます。
python sample.py min [1,-2,3]
を実行すると、min関数の引数はリストになります。
python sample.py min cat
を実行すると、min関数の引数は文字列になります。
Fire()のように空にした場合¶
Fire()
のように引数を指定しないと、そのモジュールに出てくる変数をすべて登録します。
from builtins import min, max
from fire import Fire as _Fire
_Fire()
上記のようにすると、Fire({"min": min, "max": max})
と同じになります。なお、_Fire
は、アンダースコアで始まっているため無視されます。
クラスのコマンドライン化¶
クラスを指定することもできます。
下記をsample.py
とします。
from fire import Fire
class Command:
min = min
max = max
Fire(Command)
Commandクラスは、min
とmax
のスタティックなメソッドを持っています。
このとき、Fire(Command)
とすることで、下記と同じように動作します。
c = Command()
Fire({"min": c.min, "max": c.max})
クラスを登録した場合でも、使い方は複数の関数の場合と変わりません。
実行例 |
結果 |
---|---|
|
|
|
|
|
ヘルプを表示 |
|
minのヘルプを表示 |
python sample.py min cat
を実行すると、Command().min('cat')
を実行し結果を表示します。
メソッドを定義したクラスのコマンドライン化¶
スタティックでないメソッドを定義したクラスでは、以下のようになります。
from fire import Fire
class Command:
def min(self, *args):
"""return smallest args"""
return min(args)
def max(self, *args):
"""return largest args"""
return max(args)
Fire(Command)
Commandクラスのメソッドは、スタティックでないので、第1引数は自分自身(self
)にします。
実行例は以下のようになります。
実行例 |
結果 |
---|---|
|
|
|
|
※ python sample.py min 3 -2 1
は、Command().min(3, -2, 1)
に対応し、min((3, -2, 1))
を計算し、-2
と出力されます。
※ python sample.py min cat
は、Command().min("cat")
に対応し、min(("cat", ))
を計算し、cat
と出力されることに注意してください。
__init__
メソッドを定義したクラスのコマンドライン化¶
前節では、python sample.py min
を実行すると、Command().min()
が呼ばれ、min(())
を実行しようとしてエラーになります。
一般に、min((), default=0)
のようにdefault
を指定すると、エラーにならずに0
を返すようになります。
ここでは、__init__
メソッドを作成し、min
のdefault
引数を指定できるようにします。
以下のように、Commandクラスの__init__
メソッドでdefault
を受け取れるようにし、それをmin
やmax
で使うようにします。
from fire import Fire
class Command:
def __init__(self, default=0):
self.default = default
def min(self, *args):
"""return smallest args"""
return min(args, default=self.default)
def max(self, *args):
"""return largest args"""
return max(args, default=self.default)
Fire(Command())
このようにすることで、引数が空でもエラーにならずに、0
を返します。
引数default
に値を指定するには、下記のように--default 値
というオプションをつけます。
実行例 |
結果 |
---|---|
|
|
|
|
別々の引数があるクラスのコマンドライン化¶
__init__
メソッドと、通常のメソッド(some
)の両方に引数がある場合は以下のようになります。
from fire import Fire
class Command:
def __init__(self, arg1=1):
self.arg1 = arg1
def some(self, arg2=2):
return self.arg1, arg2
Fire(Command)
実行例 |
結果 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
メソッドの引数にデフォルト値があれば、コマンドラインで省略できます。
__init__
メソッドと通常のメソッドのどちらの引数も、同じように指定できます。同名の引数の場合、__init__
メソッドが優先されます。--引数名
をつけない場合、通常のメソッドの引数と解釈されます。Python Fireへのオプションを指定したい場合は、
python sample.py -- --help
のように--
の後に書きます。
補足
もし、def some(self, arg2):
のように定義していれば、下記はarg2
が指定されていないのでエラーになります。
python sample.py some
python sample.py some --arg1 10
サブコマンドについて¶
Python Fireでは、サブコマンドを持つツールも簡単に作成できます。
from fire import Fire
class Bin:
"""Convert binary number from/to decimal number."""
def from_dec(self, n):
"""Convert binary number from decimal number."""
return bin(n)
def to_dec(self, n):
"""Convert binary number to decimal number."""
return int(str(n), 2)
class Oct:
"""Convert octal number from/to decimal number."""
def from_dec(self, n):
"""Convert octal number from decimal number."""
return oct(n)
def to_dec(self, n):
"""Convert octal number to decimal number."""
return int(str(n), 8)
class Command:
bin = Bin
oct = Oct
Fire(Command)
上記のように記述することで、binコマンドとoctコマンドが使えます。
binコマンドの値は、Binなので、Binクラスのメソッドをサブコマンドとして使えます。
octコマンドの値は、Octなので、Octクラスのメソッドをサブコマンドとして使えます。
実行例 |
結果 |
意味 |
---|---|---|
|
(略) |
コマンドのヘルプ表示 |
|
(略) |
binコマンドのサブコマンドのヘルプ表示 |
|
|
10進数の数字3を2進数の数字に変換 |
|
|
2進数の数字11を10進数の数字に変換 |
|
|
10進数の数字9を8進数の数字に変換 |
|
|
8進数の数字11を10進数の数字に変換 |