背景

之前在文章 Python 命令行参数解析方法总结 中总结了 argparserclicktyper CLIs 工具的优劣,通常情况下使用 typer。这篇文章中学习下 Google 出品的 Python Fire 命令行解析工具,发现其更加高效而且简单!

Fire

先从官方说明中了解其主要功能和优势:https://github.com/google/python-fire

Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.

  • Python Fire is a simple way to create a CLI in Python.
  • Python Fire is a helpful tool for developing and debugging Python code.
  • Python Fire helps with exploring existing code or turning other people’s code into a CLI.
  • Python Fire makes transitioning between Bash and Python easier.
  • Python Fire makes using a Python REPL easier by setting up the REPL with the modules and variables you’ll need already imported and created.

执行以下命令进行安装:

1
pip install fire

基础用法

  • fire.Fire()

    这种用法会在命令行暴露所有函数接口;

    1
    2
    3
    4
    5
    6
    7
    import fire

    def hello(name):
    return 'Hello {name}!'.format(name=name)

    if __name__ == '__main__':
    fire.Fire()

    在命令行执行即可输出:

    1
    2
    $ python example.py hello World
    Hello World!
  • fire.Fire(<fn>)

    这种用法可在 CLI 中暴露特定函数;

    1
    2
    3
    4
    5
    6
    7
    import fire

    def hello(name):
    return 'Hello {name}!'.format(name=name)

    if __name__ == '__main__':
    fire.Fire(hello)

    命令行中执行

    1
    2
    $ python example.py World
    Hello World!
  • main function

    在 main 函数中使用;

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import fire

    def hello(name):
    return 'Hello {name}!'.format(name=name)

    def main():
    fire.Fire(hello)

    if __name__ == '__main__':
    main()
  • python -m fire

    不改变任何代码仍可运行程序中的某个模块!

    1
    2
    $ python -m fire example.py hello --name=World
    Hello World!

    这就太强了,可以在命令行测试程序中的任何一个模块;

进阶用法

  1. 暴露多个函数

    • fire.Fire() 暴露所有函数;

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      import fire

      def add(x, y):
      return x + y

      def multiply(x, y):
      return x * y

      if __name__ == '__main__':
      fire.Fire()
    • fire.Fire(<dict>) 指定暴露函数名称;

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      import fire

      def add(x, y):
      return x + y

      def multiply(x, y):
      return x * y

      if __name__ == '__main__':
      fire.Fire({
      'add': add,
      'multiply': multiply,
      })
    • fire.Fire(<object>) 暴露对象内函数;

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      import fire

      class Calculator(object):

      def add(self, x, y):
      return x + y

      def multiply(self, x, y):
      return x * y

      if __name__ == '__main__':
      calculator = Calculator()
      fire.Fire(calculator)
    • fire.Fire(<class>) 暴露类 + 初始化;

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      import fire

      class Calculator(object):

      def add(self, x, y):
      return x + y

      def multiply(self, x, y):
      return x * y

      if __name__ == '__main__':
      fire.Fire(Calculator)
      1
      2
      3
      4
      $ python example.py add 10 20
      30
      $ python example.py multiply 10 20
      200

      传递参数来构造类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      import fire

      class BrokenCalculator(object):

      def __init__(self, offset=1):
      self._offset = offset

      def add(self, x, y):
      return x + y + self._offset

      def multiply(self, x, y):
      return x * y + self._offset

      if __name__ == '__main__':
      fire.Fire(BrokenCalculator)

      在命令行初始化类参数:

      1
      2
      3
      4
      $ python example.py add 10 20 --offset=0
      30
      $ python example.py multiply 10 20 --offset=0
      200
  2. 参数解析

    1
    2
    import fire
    fire.Fire(lambda obj: type(obj).__name__)

    命令行输入参数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    $ python example.py 10
    int
    $ python example.py 10.0
    float
    $ python example.py hello
    str
    $ python example.py '(1,2)'
    tuple
    $ python example.py [1,2]
    list
    $ python example.py True
    bool
    $ python example.py {name:David}
    dict

    📢 注意字符串类型需要加上 '' 或者 "" ,否则输入类型将解析错误;