Python-feu à vitesse explosive

python-fire/guide.md at master · google/python-fire · GitHub

--Une bibliothèque google qui facilite la création de cli avec python ――Il est si facile d'utiliser argparser ou quelque chose comme ça

De base

Passez la fonction au feu et appelez-la, et vous avez terminé.

import fire

def hello(name="World"):
  return "Hello %s!" % name

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

Le code ci-dessus se transforme en une commande cli comme indiqué ci-dessous.

python hello.py  # Hello World!
python hello.py --name=David  # Hello David!

Vous pouvez appeler la méthode à partir de cli en passant la classe.

import fire

class Calculator(object):
  """A simple calculator class."""

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)
python calculator.py double 10  # 20
python calculator.py double --number=15  # 30

Créer plusieurs commandes

Tout d'abord, ce qui arrive à la commande cli est le suivant.

$ python example.py add 10 20
30
$ python example.py multiply 10 20
200

Il existe plusieurs façons d'y parvenir:

Appelez simplement seulement le feu

--Toutes les fonctions du fichier sont converties en commandes cli

import fire

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

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

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

--Même s'il y a une variable dans le fichier, elle peut également être appelée avec une commande

import fire
english = 'Hello World'
spanish = 'Hola Mundo'
fire.Fire()
$ python example.py english
Hello World
$ python example.py spanish
Hola Mundo

passer dict et tirer

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,
  })

Passer une instance d'une classe de commande uniquement

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)

Passer la classe de commande uniquement elle-même

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)
$ python example.py add 10 20 --offset=0
30
$ python example.py multiply 10 20 --offset=0
200

Regroupement de commandes

class IngestionStage(object):

  def run(self):
    return 'Ingesting! Nom nom nom...'

class DigestionStage(object):

  def run(self, volume=1):
    return ' '.join(['Burp!'] * volume)

  def status(self):
    return 'Satiated.'

class Pipeline(object):

  def __init__(self):
    self.ingestion = IngestionStage()
    self.digestion = DigestionStage()

  def run(self):
    self.ingestion.run()
    self.digestion.run()

if __name__ == '__main__':
  fire.Fire(Pipeline)
$ python example.py run
Ingesting! Nom nom nom...
Burp!
$ python example.py ingestion run
Ingesting! Nom nom nom...
$ python example.py digestion run
Burp!
$ python example.py digestion status
Satiated.

Accéder aux propriétés de la classe

from airports import airports

import fire

class Airport(object):

  def __init__(self, code):
    self.code = code
    self.name = dict(airports).get(self.code)
    self.city = self.name.split(',')[0] if self.name else None

if __name__ == '__main__':
  fire.Fire(Airport)
$ python example.py --code=JFK code
JFK
$ python example.py --code=SJC name
San Jose-Sunnyvale-Santa Clara, CA - Norman Y. Mineta San Jose International (SJC)
$ python example.py --code=ALB city
Albany-Schenectady-Troy

Appliquer la fonction à la valeur de retour de la commande

#Le code lui-même est l'exemple de l'aéroport ci-dessus
$ python example.py --code=ALB city upper
ALBANY-SCHENECTADY-TROY

--C'est pratique car vous pouvez enchaîner les méthodes les unes après les autres si toutes les méthodes de la classe de commande se renvoient elles-mêmes.

import fire

class BinaryCanvas(object):
  """A canvas with which to make binary art, one bit at a time."""

  def __init__(self, size=10):
    self.pixels = [[0] * size for _ in range(size)]
    self._size = size
    self._row = 0  # The row of the cursor.
    self._col = 0  # The column of the cursor.

  def __str__(self):
    return '\n'.join(' '.join(str(pixel) for pixel in row) for row in self.pixels)

  def show(self):
    print(self)
    return self

  def move(self, row, col):
    self._row = row % self._size
    self._col = col % self._size
    return self

  def on(self):
    return self.set(1)

  def off(self):
    return self.set(0)

  def set(self, value):
    self.pixels[self._row][self._col] = value
    return self

if __name__ == '__main__':
  fire.Fire(BinaryCanvas)
$ python example.py move 3 3 on move 3 6 on move 6 3 on move 6 6 on move 7 4 on move 7 5 on
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 1 0 0 0
0 0 0 0 1 1 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0

Personnaliser la classe de commande pour l'affichage

--Si la valeur de retour de la méthode appelée est une classe, cette méthode __str__ sera appelée.

Divers appels de fonction de cli

import fire

class Building(object):

  def __init__(self, name, stories=1):
    self.name = name
    self.stories = stories

  def climb_stairs(self, stairs_per_story=10):
    for story in range(self.stories):
      for stair in range(1, stairs_per_story):
        yield stair
      yield 'Phew!'
    yield 'Done!'

if __name__ == '__main__':
  fire.Fire(Building)
$ python example.py --name="Sherrerd Hall" --stories=3 climb_stairs 10
$ python example.py --name="Sherrerd Hall" climb_stairs --stairs_per_story=10
$ python example.py --name="Sherrerd Hall" climb_stairs --stairs-per-story 10
$ python example.py climb-stairs --stairs-per-story 10 --name="Sherrerd Hall"

Autre

Créer un cli sans incorporer le feu dans le code lui-même

def hello(name):
  return 'Hello {name}!'.format(name=name)
python -m fire example hello --name=World
# => Hello World!

Spécifier le nom de l'argument dans cli

def say(name, content):
	print(name + ", " + content)

fire.Fire(say)
python say.py taro hello # taro, hello
python say.py --content=hello --name=taro # taro, hello

Si l'argument passé par cli est obligatoire ou facultatif

def say(name, content="hello"):
	print(name + ", " + content)

fire.Fire(say)
python say.py taro # => taro, hello
python say.py # => error!

Comment passer la liste comme argument de cli

python some.py "[test, test1]”

Ajouter un message d'aide à arg

--Si vous écrivez une description de l'argument dans docstring, ce sera utile

def main(a):
	"""
	a: hogehoge
	"""

Recommended Posts

Python-feu à vitesse explosive
[Easy explosion speed 2nd] Déployez Streamlit sur heroku