Argparse w wierszu poleceń
Pracując w interfejsie wiersza poleceń – CLI nie sposób nie wspomnieć o module argparse. Pozwala on na definiowanie oraz dodawanie argumentów w przyjazny sposób do wywoływanego programu w wierszu poleceń. Innymi słowy umożliwia szybkie utworzenie solidnego interfejsu w CLI opartego na zdefiniowanych argumentach. Można w zasadzie to zawęzić do stworzenia parsera zawierającego ustalone argumenty, pozycyjne i/lub opcjonalne , wywołanie tego parsera i następnie jego zastosowanie przy wywoływanym skrypcie. W bardzo uproszonym skrócie pozwala nam na utworzenie systemu argumentów do wywoływanego skryptu w wierszu poleń.
Argumenty w praktyce
Posługując się wzorem na pole trójkąta równoramiennego wykorzystanie argparse w najprostszej formie może wyglądać jak poniżej:
import argparse
parser = argparse.ArgumentParser(description="Pole trójkąta równoramiennego")
parser.add_argument('bok', type=int, help ='Bok trójkąta równoramiennego')
parser.add_argument('wysokość', type=int, help ='Wysokość trójkąta równoramiennego')
argumenty = parser.parse_args()
def pole_trojkata(bok, wysokosc):
wynik = (bok * wysokosc)/2
return wynik
if __name__ == '__main__':
print (pole_trojkata(argumenty.bok,argument.wysokosc))
Wywołując skrypt z dopiskiem -h widzimy pełną definicję argumentów
PS E:\Python > python powierchnia.py -h
usage: powierchnia.py [-h] bok wysokość
Pole trójkąta równoramiennego
positional arguments:
bok Bok trójkąta równoramiennego
wysokość Wysokość trójkąta równoramiennego
optional arguments:
-h, --help show this help message and exit
Natomiast wywołując z parametrami otrzymamy wynik
PS E:\Python > python powierchnia.py 2 4
4.0
Argumenty pozycyjne i opcjonalne
Jeżeli dodamy „–” do nazwy argumentów to staną się one opcjonalne i w przypadku nie podania zostanie wykorzystane default value, którą również ustawimy. Dodamy również krótki zapis z pojedynczymi literami i znakiem „-„
parser.add_argument('-b','--bok', type=int, help ='Bok trójkąta równoramiennego', default=1)
parser.add_argument('-w','--wysokosc', type=int, help ='Wysokość trójkąta równoramiennego', default=1)
PS E:\Python > python powierchnia.py
0.5
Przy czym również te argumentu nie będą już pozycyjne, a więc trzeba je podawać z nazwą w wywołaniu, jeżeli taki mamy zamiar
PS E:\Python > python powierchnia.py --bok 2 --wysokosc 2
2.0
Możemy również wywołać poprzez zapis krótki:
PS E:\Python > python powierchnia.py -b 2 -w 2
2.0
Możemy również ustawić argumenty jako wymagane dodając parametr required = True. W takiej sytuacji oczywiście parametr default nie ma dalszego sensu.
parser.add_argument('-b','--bok', type=int, required=True, help ='Bok trójkąta równoramiennego')
parser.add_argument('-w','--wysokosc', type=int, required=True, help ='Wysokość trójkąta równoramiennego')
Flagi store_true i store_false
Innym istotnym typem argumentu jest store_true lub store_false. Są to tzw. flagi i przetrzymują jedynie wartości prawda bądź fałsz. Czyli same w sobie są wartością i nie wymagają dopisywania niczego więcej.
Możemy nieco zmodyfikować nasz kod poprzez dodanie argumentu flagowego do drukowania opisu trójkąta. Może to wyglądać następująco:
import argparse
parser = argparse.ArgumentParser(description="Pole trójkąta równoramiennego")
parser.add_argument('-b','--bok', type=int, required=True, help ='Bok trójkąta równoramiennego')
parser.add_argument('-w','--wysokosc', type=int, required=True, help ='Wysokość trójkąta równoramiennego')
parser.add_argument('-o','--opis', action='store_true' , help ='Opis trójkąta')
argumenty = parser.parse_args()
def pole_trojkata(bok, wysokosc):
wynik = (bok * wysokosc)/2
return wynik
if __name__ == '__main__':
pole = pole_trojkata(argumenty.bok,argumenty.wysokosc)
if argumenty.opis:
print("Trójkąt o boku długości %s i wysokości %s ma pole o powierzchni %s." % (argumenty.bok, argumenty.wysokosc, pole))
else:
print (pole)
Wtedy wywołanie z parametrem „-o” będzie wyglądało jak niżej
PS E:\Python > python powierchnia.py -b 2 -w 2 -o
Trójkąt o boku długości 2 i wysokości 2 ma pole o powierzchni 2.0.
Czytelniejszy help z metavar
Często wykorzystywanym parametrem jest matavar, który definiuje wyświetlaną nazwę argumentu w help. Najczęściej ustawianie tego jako pustego znaku znacząco zwiększa czytelność komendy help paresera. Przykładowo dla obecnego skryptu komenda -h zwróci poniższe:
usage: powierchnia.py [-h] -b BOK -w WYSOKOSC [-o]
Pole trójkąta równoramiennego
optional arguments:
-h, --help show this help message and exit
-b BOK, --bok BOK Bok trójkąta równoramiennego
-w WYSOKOSC, --wysokosc WYSOKOSC
Wysokość trójkąta równoramiennego
-o, --opis Opis trójkąta
Natomiast dodanie parametru metavar=” w argumentach bok i wysokość
parser.add_argument('-b','--bok', type=int, required=True, metavar='', help ='Bok trójkąta równoramiennego')
parser.add_argument('-w','--wysokosc', type=int, required=True, metavar='',help ='Wysokość trójkąta równoramiennego')
Da nam poniższy rezultat:
usage: powierchnia.py [-h] -b -w [-o]
Pole trójkąta równoramiennego
optional arguments:
-h, --help show this help message and exit
-b , --bok Bok trójkąta równoramiennego
-w , --wysokosc Wysokość trójkąta równoramiennego
-o, --opis Opis trójkąta
W tym przypadku jest to znacznie czytelniejsza forma.
Konkluzja
Argparse jest niezwykle użyteczną formą organizowania argumentów w wierszu poleceń. Pozwala w prosty sposób ustandaryzować wykorzystywanie i uruchamianie skryptów w CLI. Warto również wspomnieć, że jest częścią biblioteki standardowej.