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})とすることで、minmaxの2つのコマンドが使えます。

python sample.py -hまたはpython sample.pyでヘルプを表示します。 ヘルプを見ると、python sample.py コマンドのように使えて、コマンドとしてminmaxが選べることがわかります。

  • 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クラスは、minmaxのスタティックなメソッドを持っています。 このとき、Fire(Command)とすることで、下記と同じように動作します。

c = Command()
Fire({"min": c.min, "max": c.max})

クラスを登録した場合でも、使い方は複数の関数の場合と変わりません。

実行例 結果
python sample.py min cat a
python sample.py max cat t
python sample.py ヘルプを表示
python sample.py min -- --help 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 -2
python sample.py max 3 -2 1 3

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__メソッドを作成し、mindefault引数を指定できるようにします。

以下のように、Commandクラスの__init__メソッドでdefaultを受け取れるようにし、それをminmaxで使うようにします。

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 というオプションをつけます。

実行例 結果
python sample.py min 0
python sample.py max --default -1 -1

別々の引数があるクラスのコマンドライン化

__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)
実行例 結果
python sample.py some [1, 2]
python sample.py some --arg1 10 [10, 2]
python sample.py some 20 [1, 20]
python sample.py some --arg2 20 [1, 20]
python sample.py some --arg1 10 20 [10, 20]
python sample.py some --arg1 10 --arg2 20 [10, 20]
  • メソッドの引数にデフォルト値があれば、コマンドラインで省略できます。

  • __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クラスのメソッドをサブコマンドとして使えます。

実行例 結果 意味
python sample.py (略) コマンドのヘルプ表示
python sample.py bin (略) binコマンドのサブコマンドのヘルプ表示
python sample.py bin from_dec 3 0b11 10進数の数字3を2進数の数字に変換
python sample.py bin to_dec 11 3 2進数の数字11を10進数の数字に変換
python sample.py oct from_dec 9 0o11 10進数の数字9を8進数の数字に変換
python sample.py oct to_dec 11 9 8進数の数字11を10進数の数字に変換
当コンテンツの知的財産権は株式会社ビープラウドに所属します。詳しくは利用規約をご確認ください。