Prodesire
The sample code and history articles involved have been synchronized to the HelloGithub-Team repository
One, foreword
In our first “Fire Primer,” we took a first look at the simple steps to use fire and learned how to use it Pythonic.
Today we’ll take a closer look at fire’s subcommands, nested commands, and property access capabilities.
This series of articles uses Python 3 as the interpreter by default. If you are still using Python 2, be aware of the differences in syntax and library usageCopy the code
Second, the function of
2.1 the son command
There are several ways to implement subcommands using fire:
2.1.1 Define some functions using fire.fire ()
The simplest way to implement a subcommand is to define several functions, each of which is implicitly a subcommand name, and then call fire.fire () to parse all functions in the current module into handlers for the corresponding subcommand.
import fire
def add(x, y):
return x + y
def multiply(x, y):
return x * y
if __name__ == '__main__':
fire.Fire()
Copy the code
We can then call it from the command line like this:
$ python example.py add 10 20
30
$ python example.py multiply 10 20
200
Copy the code
How to identify parameter types, such as add 10 and 20 as numbers rather than strings, will be explained in the parameter parsing section of the next article.
2.1.2 Define some functions using fire.fire ()
In version 2.1.1, all functions are treated as subcommands. Sometimes we just want to treat part of a function as a subcommand, or we want the subcommand name to be different from the function name. At this point we can explicitly tell the fire through the dictionary object.
The dictionary object is of the form {‘ subcommand name ‘: function}. For example, in the previous example, we wanted the final subcommands to be add and mul, so we could write:
fire.Fire({
'add': add,
'mul': multiply,
})
Copy the code
We can then call it from the command line like this:
$ python example.py add 10 20
30
$ python example.py mul 10 20
200
Copy the code
2.1.3 Define classes and methods using fire.fire ()
Classes and methods are defined in much the same way as functions are defined in the last article, except that they are organized in terms of classes.
The class is then instantiated and the instantiated object is mostly fire.Fire:
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)
Copy the code
2.1.4 Define classes and methods using fire.fire ()
The only difference from 2.1.3 is that we use a class instead of an instance object as an entry to fire.Fire:
fire.Fire(Calculator)
Copy the code
The basic function of the pass class is the same as that of the instance object, but the pass class has an additional feature: if parameters are defined in the constructor, they are used as option parameters for the entire command line program.
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)
Copy the code
The help commands are as follows:
$ python example.py --help
INFO: Showing help with the command 'example.py -- --help'.
NAME
example.py
SYNOPSIS
example.py <flags>
FLAGS
--offset=OFFSET
Copy the code
This shows that the offset in the constructor brokencalculator.__init__ (self, offset=1) is automatically converted to the global option argument –offset on the command line, with a default value of 1.
We can call this from the command line:
$ python example.py add 10 20
31
$ python example.py multiply 10 20
201
$ python example.py add 10 20 --offset=0
30
$ python example.py multiply 10 20 --offset=0
200
Copy the code
2.2 Command Group/Nested Commands
To implement nested commands, organize multiple classes as shown in the following example:
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)
Copy the code
In the example above:
IngestionStage
Subcommands are implementedrun
DigestionStage
Subcommands are implementedrun
和status
Pipeline
In the constructor ofIngestionStage
Instantiated asingestion
That will beDigestionStage
Instantiated asdigestion
, put these two in a command group, thus supporting:ingestion run
digestion run
digestion status
Pipeline
Subcommands are implementedrun
Therefore, the entire command line program supports the following commands:
run
ingestion run
digestion run
digestion status
We can then call it from the command line like this:
$ 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.
Copy the code
2.3 Attribute Access
Property access is a unique feature of Fire compared to other command line libraries. The access attribute is to get the value of the preset attribute.
For example, you specify –code on the command line to tell the program what code to query for, and then you want to return the zipcode via the zipcode attribute and the city name via the city attribute. Properties can then be implemented as instance member properties:
import fire
cities = {
'hz': (310000.'hangzhou'),
'bj': (100000.'Beijing'),}class City(object):
def __init__(self, code):
info = cities.get(code)
self.zipcode = info[0] if info else None
self.city = info[1] if info else None
if __name__ == '__main__':
fire.Fire(City)
Copy the code
The usage is as follows:
$python example.py --code bj zipcode 100000 $python example.py --code Hz cityCopy the code
Third, summary
Not only is implementing subcommands and nested commands with Fire much simpler and cleaner than other command line libraries, but fire also provides the unique ability to access properties.
In the next article, we’ll take a closer look at Fire and introduce more advanced features like chained function calls, custom serialization, parameter parsing, fire options, and more.
“Explain Open Source Project series” — let the people who are interested in open source projects not be afraid, let the initiator of open source projects not be alone. Follow along as you discover the joys of programming, use, and how easy it is to get involved in open source projects. Welcome to leave a message to contact us, join us, let more people fall in love with open source, contribute to open source ~