Jak analyzovat argumenty příkazového řádku v Pythonu
Chcete spouštět skripty Pythonu s argumenty příkazového řádku? Naučte se analyzovat argumenty příkazového řádku pomocí modulů sys, getopt a argparse v Pythonu.
Když v Pythonu chcete číst uživatelský vstup, použijete funkci input(). U některých aplikací však můžete chtít předat určité argumenty při spouštění skriptu na příkazovém řádku.
V tomto tutoriálu se naučíme, jak spustit skript Python s možnostmi a argumenty na příkazovém řádku. Poté se naučíme, jak používat vestavěné moduly Pythonu k analýze takových voleb a argumentů.
Pojďme začít!
Pochopení sys.argv v Pythonu
Pokud jste programovali v C, víte, že jedním z nejjednodušších způsobů předávání argumentů programu je příkazový řádek. Chcete-li tak učinit, můžete strukturovat hlavní funkci takto:
#include<stdio.h> int main(int argc, char **argv){ //argc: argument count //argv: argument vector //do something on the args return 0; }
Zde argc znamená počet argumentů a argv znamená vektor argumentu.
Spouštění skriptů Python s argumenty příkazového řádku
V Pythonu můžete spustit skript Python na příkazovém řádku pomocí python3 filename.py. Přitom můžete také předat libovolný počet argumentů příkazového řádku:
$ python3 filename.py arg1 arg2 ... argn
Modul sys poskytuje přímou podporu pro přístup a zpracování těchto argumentů příkazového řádku. sys.argv je seznam všech argumentů příkazového řádku, které předáváme, když spouštíme skript Python.
Zde je příklad, kdy spouštíme main.py s argumenty příkazového řádku:
$ python3 main.py hello world python script
Můžeme procházet argumentový vektor pomocí jednoduchého cyklu for a funkce výčtu:
# main.py import sys for idx, arg in enumerate(sys.argv): print(f"arg{idx}: {arg}")
# Output arg0:main.py arg1:hello arg2:world arg3:python arg4:script
Vidíme, že první argument (na indexu 0) je název souboru Python. A následné argumenty začínají na indexu 1.
Toto je minimální pracovní program, který přijímá a zpracovává argumenty příkazového řádku. Vidíme však některé problémy:
- Jak uživatelé programu vědí, jaké argumenty mají předat?
- A co tyto argumenty znamenají?
To není moc jasné. K vyřešení tohoto problému můžete použít moduly getopt nebo argparse. A to se dozvíme v dalších dílech.✅
Analýza argumentů příkazového řádku pomocí getopt Pythonu
Pojďme se naučit, jak analyzovat argumenty příkazového řádku pomocí vestavěného modulu getopt.
Po importu getopt z modulu getopt můžete zadat argumenty k analýze a krátké volby a dlouhé volby, se kterými se má skript spustit. Musíme analyzovat všechny argumenty začínající na indexu 1 v sys.argv. Takže řez k analýze je sys.argv[1:].
Zde budeme potřebovat řetězec zprávy a název souboru. Použijme m a f jako krátké možnosti a zprávu a soubor jako dlouhé možnosti.
Jak ale zajistíme, že konkrétní možnost vyžaduje argument?
- U krátkých voleb můžete nastavit, aby volba vyžadovala argument přidáním dvojtečky (:) za krátký název volby.
- Podobně v dlouhých možnostech můžete za dlouhou možnost přidat znak =. Můžeme zachytit tyto možnosti a jejich příslušné argumenty.
Když je přidáme, budeme mít v main.py následující kód:
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="]) print(opts) print(args)
Zde proměnná opts obsahuje možnosti a argumenty jako seznam n-tic. Jakýkoli další poziční argument, který předáme, bude shromážděn v proměnné args.
Můžeme předat zprávu a název souboru ke spuštění skriptu a můžeme použít buď krátké volby, nebo dlouhé volby.
Spuštěním main.py pomocí dlouhých možností máme:
$ python3 main.py --message hello --file somefile.txt
Možnosti a argumenty máme jako n-tice v proměnné opts. Protože jsme nepředali žádný poziční argument, argumenty jsou prázdný seznam.
# Output [("--message', 'hello'), ('--file', 'somefile.txt')] []
Ekvivalentně můžeme také použít krátké možnosti, jak je uvedeno:
$ python3 main.py -m hello -f somefile.txt
# Output [('-m', 'hello'), ('-f', 'somefile.txt')] []
⚠️ Krátkou volbu -m v tomto příkladu nelze zaměňovat s příznakem příkazového řádku -m, který se používá ke spuštění modulu jako hlavního modulu při spouštění skriptu Python.
Například použijete python3 -m unittest main.py ke spuštění unittestu jako hlavního modulu při spouštění main.py.
Zmínili jsme, že všechny ostatní poziční argumenty, které předáme, budou shromažďovány v proměnné args. Zde je příklad:
$ python3 main.py -m hello -f somefile.txt another_argument
Seznam argumentů obsahuje poziční argument jiný_argument.
# Output [('-m', 'hello'), ('-f', 'somefile.txt')] ['another_argument']
Zde je seznam n-tic. Můžeme to tedy procházet, rozbalit n-tici a vytáhnout argumenty odpovídající konkrétním možnostem.
Ale co uděláme s názvem souboru a zprávou poté, co zpracujeme tyto argumenty? Soubor otevřeme v režimu zápisu a do souboru zapíšeme řetězec zprávy převedený na velká písmena.
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="]) print(opts) print(args) for option, argument in opts: if option == "-m': message = argument if option == '-f': file = argument with open(file,'w') as f: f.write(message.upper())
Spusťte main.py s krátkými možnostmi a argumenty příkazového řádku.
$ python main.py -m hello -f thisfile.txt [('-m', 'hello'), ('-f', 'thisfile.txt')] []
Po spuštění main.py můžeme vidět ‚thisfile.txt‘ v našem pracovním adresáři. Obsahuje řetězec ‚hello‘ převedený na velká písmena (‚HELLO‘).
$ ls main.py thisfile.txt
$ cat thisfile.txt HELLO
Jak analyzovat argumenty příkazového řádku pomocí Argparse
Modul argparse, také zabudovaný do standardní knihovny Pythonu, poskytuje funkce pro analýzu argumentů příkazového řádku a také vytváření rozhraní příkazového řádku.
Chcete-li analyzovat argumenty příkazového řádku, importujme třídu ArgumentParser z modulu argparse. Zde jsme vytvořili instanci arg_parser, objekt ArgumentParser:
from argparse import ArgumentParser arg_parser = ArgumentParser()
Dále bychom chtěli přidat dva argumenty příkazového řádku:
- zpráva: řetězec zprávy a
- file: název souboru, se kterým chceme pracovat.
Nyní zavoláme metodu add_argument() na arg_parser, abychom přidali oba tyto argumenty. Ve volání metody add_argument() můžete nastavit help na řetězec (popis argumentu).
arg_parser.add_argument('message',help='message string') arg_parser.add_argument('file',help='filename')
Doposud jsme vytvořili instanci arg_parser a přidali argumenty příkazového řádku. Když je program spuštěn na příkazovém řádku, můžete pomocí metody parse_args() na arg_parser získat hodnoty argumentů.
Zde zachytíme jmenný prostor argumentů v proměnné args. Hodnoty argumentů tedy můžete získat pomocí args.argument_name.
Po získání hodnot argumentů zapíšeme do souboru řetězec zprávy se zaměněnými velkými a malými písmeny (pomocí řetězcové metody swapcase()).
args = arg_parser.parse_args() message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Když to všechno dáme dohromady, zde je náš soubor main.py:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('message',help='message string') arg_parser.add_argument('file',help='filename') args = arg_parser.parse_args() print(args) message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Pochopení použití argumentů příkazového řádku
Chcete-li porozumět použití argumentů při spuštění main.py, můžete použít volbu –help long, jak je znázorněno:
$ python3 main.py --help usage: main.py [-h] message file positional arguments: message message string file filename optional arguments: -h, --help show this help message and exit
Neexistují žádné volitelné argumenty a zpráva i soubor jsou povinné poziční argumenty. Alternativně můžete také použít krátkou volbu -h:
$ python3 main.py -h usage: main.py [-h] message file positional arguments: message message string file filename optional arguments: -h, --help show this help message and exit
Jak je vidět, oba argumenty jsou ve výchozím nastavení pozičními argumenty. Pokud tedy nezadáte jeden nebo více z těchto argumentů, narazíte na chyby.
Zde jsme předali poziční argument (Ahoj) pro řetězec zprávy, ale nedodali jsme žádnou hodnotu pro argument souboru.
A dostaneme chybu oznamující, že je vyžadován argument souboru.
$ python3 main.py Hello usage: main.py [-h] message file main.py: error: the following arguments are required: file
Když spustíme main.py s oběma pozičními argumenty, vidíme, že jmenný prostor args obsahuje hodnoty argumentů.
$ python3 main.py Hello file1.txt
# Output Namespace(file="file1.txt", message="Hello")
Nyní, když prozkoumáme obsah současného pracovního adresáře, uvidíme, že skript vytvoří soubor ‚file1.txt‘:
$ ls file1.txt main.py
Původní řetězec zprávy je ‚Ahoj‘; po záměně případu je řetězec zprávy v souboru ‚file1.txt‘ ‚hELLO‘.
$ cat file1.txt hELLO
Jak nastavit argumenty příkazového řádku jako volitelné
Aby byly tyto argumenty příkazového řádku nepovinné, můžete před název argumentu uvést –.
Upravme main.py tak, aby byly argumenty zprávy i souboru nepovinné.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='message string') arg_parser.add_argument('--file',help='filename')
Protože oba argumenty příkazového řádku jsou volitelné, můžeme pro tyto argumenty nastavit výchozí hodnoty.
if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt"
V tomto okamžiku obsahuje soubor main.py následující kód:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='message string') arg_parser.add_argument('--file',help='filename') args = arg_parser.parse_args() print(args) if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt" with open(file,'w') as f: f.write(message.swapcase())
Pokud zkontrolujeme použití, uvidíme, že zpráva i soubor jsou nepovinné argumenty. To znamená, že nyní můžete spustit main.py bez obou těchto argumentů.
$ python3 main.py --help usage: main.py [-h] [--message MESSAGE] [--file FILE] optional arguments: -h, --help show this help message and exit --message MESSAGE message string --file FILE filename
$ python3 main.py
V oboru názvů argumentů jsou soubor i zpráva Žádné.
# Output Namespace(file=None, message=None)
Vidíme, že je použit výchozí název souboru a zpráva ‚myfile.txt‘ a ‚Python3‘. Soubor ‚myfile.txt‘ je nyní v pracovním adresáři:
$ ls file1.txt main.py myfile.txt
A obsahuje řetězec ‚Python3‘ s prohozenými písmeny:
$ cat myfile.txt pYTHON3
Můžete také použít oba argumenty –message a –file, aby byl příkaz čitelnější.
$ python3 main.py --message Coding --file file2.txt
# Output Namespace(file="file2.txt", message="Coding")
V pracovním adresáři vidíme soubor ‚file2.txt‘:
$ ls file1.txt file2.txt main.py myfile.txt
A podle očekávání obsahuje řetězec ‚coDING‘.
$ cat file2.txt cODING
Závěr
Zde je souhrn toho, co jsme se naučili v tomto tutoriálu:
- Podobně jako v programovacím jazyce C můžete v Pythonu přistupovat k argumentům příkazového řádku procházením argumentového vektoru sys.argv. sys.argv[0] je název skriptu Python. Takže nás zajímá analýza argumentů sys.argv[1:].
- Chcete-li však zlepšit čitelnost a přidávat možnosti, můžete použít moduly getopt a argparse.
- Pomocí modulu getopt můžete analyzovat seznam argumentů příkazového řádku počínaje indexem 1 až do konce seznamu. Můžete zadat krátké i dlouhé varianty.
- Když volba přebírá argument, můžete zadat dvojtečku (:) a = za krátkou a dlouhou volbu.
- S modulem argparse Pythonu můžete vytvořit instanci objektu ArgumentParser a použít metodu add_argument() k přidání požadovaného pozičního argumentu. Use — před názvem argumentu, aby byl volitelný.
- Chcete-li načíst hodnoty argumentů příkazového řádku, zavolejte metodu parse_args() na objektu ArgumentParser.
Dále se naučte, jak provádět bezpečné hashování v Pythonu.