Áttekintés
Mivel a Python nagyon népszerű programozási nyelv, valamint támogatja a legtöbb operációs rendszert és számos könyvtárat, amelyek megkönnyítik a parancssori argumentumok feldolgozását – széles körben használják számos célra parancssori eszközök létrehozására. Ezek az eszközök az egyszerű CLI-alkalmazásoktól a bonyolultabbakig, például az AWS-ig terjedhetnek. awscli eszköz.
Az ehhez hasonló összetett eszközöket általában a felhasználó vezérli parancssori argumentumokat, amely lehetővé teszi a felhasználó számára, hogy konkrét parancsokat, beállításokat stb. Ezek a beállítások például utasíthatják az eszközt, hogy további információkat adjon ki, adatokat olvasson be egy megadott forrásból, vagy küldjön kimenetet egy bizonyos helyre.
Az argumentumok általában eltérően kerülnek átadásra a CLI-eszközöknek, az operációs rendszertől függően:
- Unix-szerű:
-
majd egy levél, mint pl-h
vagy--
utána egy szó, mint--help
- Windows:
/
vagy egy betű, vagy szó, mint például/help
Ezek a különböző megközelítések történelmi okok miatt léteznek. A Unix-szerű rendszereken sok program támogatja az egy- és kétkötőjeles jelölést. Az egykötőjeles jelölést többnyire egybetűs opciókkal használják, míg a dupla kötőjelek olvashatóbb opciókat jelenítenek meg, ami különösen hasznos olyan összetett opciók esetén, amelyeknek pontosabbnak kell lenniük.
Megjegyzések: Ebben a cikkben kizárólag a Unix-szerű formátumra fogunk összpontosítani -
és a --
.
Ne feledje, hogy az argumentum neve és jelentése is egy programra jellemző – nincs általános definíció, kivéve néhány általános konvenciót, mint pl. --help
az eszköz használatával kapcsolatos további információkért. A Python-szkript fejlesztőjeként Ön dönti el, mely argumentumokat adja meg a hívónak, és mit tegyen. Ehhez megfelelő értékelésre van szükség.
Ahogy az elérhető argumentumok listája növekszik, a kód egyre összetettebb lesz a pontos elemzésük során. Szerencsére a Pythonban számos könyvtár áll rendelkezésre, amelyek segítenek ebben. Leírunk néhány leggyakoribb megoldást, a „csináld magad”-tól kezdve sys.argv
, a „végzett érted” megközelítéshez argparse
.
Parancssori argumentumok kezelése Python segítségével
A Python 3+ és a körülötte lévő ökoszisztéma számos különböző módot támogat a parancssori argumentumok kezelésére. Vannak sok könyvtárak, amelyek elbűvölik a parancssori argumentumok elemzését.
A beépített módja a sys
modult. A neveket és a használatát tekintve közvetlenül kapcsolódik a C könyvtárhoz (libc
).
A második út a getopt
modul, amely mind a rövid, mind a hosszú opciókat kezeli, beleértve a paraméterértékek kiértékelését is.
A argparse modul, amely abból származik optparse
modul (a Python 2.7-ig elérhető).
A docopt
modult, ami az elérhető a GitHub-on, szintén lehetővé teszi ugyanazt a funkciót.
Nemrég a absl
könyvtár is egyre nagyobb lendületet kapott, mint a pótlás eszköze optparse
és a getopt()
.
Mindegyik módszernek megvannak a maga előnyei és hátrányai, ezért érdemes mindegyiket értékelni, hogy megtudja, melyik felel meg leginkább az Ön igényeinek.
A sys modul
Ez egy alapmodul, amelyet a kezdetektől a Pythonnal szállítottak. Nagyon hasonló megközelítést alkalmaz a C könyvtár használatához argc
/argv
hogy hozzáférjen az érvekhez. A sys modul nevű egyszerű listastruktúrában valósítja meg a parancssori argumentumokat sys.argv
.
Minden listaelem egyetlen argumentumot képvisel. A lista első eleme,
sys.argv[0]
, a Python szkript neve. A lista többi eleme,sys.argv[1]
nak neksys.argv[n]
, a parancssori argumentumok 2-től n-ig.
Az argumentumok közötti határolóként szóközt használunk. A szóközt tartalmazó argumentumértékeket idézőjelekkel kell körülvenni, hogy megfelelően értelmezhetőek legyenek sys
.
A megfelelője argc
csak a lista elemeinek száma. Ennek az értéknek a megszerzéséhez használja a Python-t len()
operátor. Ezt a későbbiekben egy kódpéldán mutatjuk be.
Az első CLI-argumentum kinyomtatása
Ebben az első példában a szkriptünk határozza meg a hívás módját. Ezt az információt az első parancssori argumentum tárolja, 0-val indexelve. Az alábbi kód megmutatja, hogyan szerezheti meg Python-szkriptjének nevét:
import sys
print("The script has the name %s" % (sys.argv[0])
Mentse el ezt a kódot egy nevű fájlba arguments-program-name.py
, majd hívja az alábbiak szerint. A kimenet a következő, és tartalmazza a fájl nevét, beleértve a teljes elérési utat:
$ python arguments-program-name.py
The script has the name arguments-program-name.py
$ python /home/user/arguments-program-name.py
The script has the name /home/user/arguments-program-name.py
Amint a fenti második hívásból is látható, nem csak a Python-fájl nevét kapjuk meg, hanem a teljes elérési utat is, amelyet annak hívására használnak.
Az érvek számának számolása
Ebben a második példában egyszerűen megszámoljuk a beépített parancssori argumentumok számát len()
módszer. sys.argv
ez a lista, amelyet meg kell vizsgálnunk. Az alábbi kódban megkapjuk az argumentumok számát, majd kivonjuk az 1-et, mert az egyik argumentum (azaz az első) mindig a fájl neveként van beállítva, ami nem mindig hasznos számunkra. Így a felhasználó által átadott argumentumok tényleges száma len(sys.argv) - 1
:
import sys
arguments = len(sys.argv) - 1
print ("The script is called with %i arguments" % (arguments))
Mentse el és nevezze el ezt a fájlt arguments-count.py. Az alábbiakban látható néhány példa a szkript meghívására. Ez három különböző forgatókönyvet foglal magában:
- Hívás további parancssori argumentumok nélkül
- Felhívás két érvvel
- Hívás két argumentummal, ahol a második egy szóközt tartalmazó idézőjeles karakterlánc
$ python arguments-count.py
The script is called with 0 arguments
$ python arguments-count.py --help me
The script is called with 2 arguments
$ python arguments-count.py --option "long string"
The script is called with 2 arguments
Ismétlés érvekkel
A harmadik példánk a Python-szkriptnek küldött összes argumentumot adja ki, kivéve magát a program nevét. Ezért a parancssori argumentumokat a következővel kezdjük második listaelem. Emlékezzünk vissza, hogy ez az index 1, mivel a listák Pythonban 0-alapúak:
import sys
arguments = len(sys.argv) - 1
position = 1
while (arguments >= position):
print ("Parameter %i: %s" % (position, sys.argv[position]))
position = position + 1
Az alábbiakban meghívjuk a kódunkat, amelyet az arguments-output.py fájlba mentettünk. Az előző példánkhoz hasonlóan a kimenet három különböző hívást mutat be:
- Felhívás minden érv nélkül
- Felhívás két érvvel
- Hívás két argumentummal, ahol a második argumentum egy szóközt tartalmazó idézőjeles karakterlánc
$ python arguments-output.py
$ python arguments-output.py --help me
Parameter 1: --help
Parameter 2: me
$ python arguments-output.py --option "long string"
Parameter 1: --option
Parameter 2: long string
Ne feledje, az idézett karakterlánc-példa bemutatásának lényege az, hogy a paramétereket általában szóköz választja el, hacsak nem idézőjelek veszik körül.
Abseil zászlók (absl
)
Az Abseil Flags könyvtárának célja, hogy parancssori argumentumokat vigyen a termelésbe, elosztott parancssori argumentumokkal. Amikor egy modul parancssori jelzőket használ, és egy másik modulba – a másik modulba – importálódik importálja a zászlókat is, és feldolgozhatja azokat az importált modulba való továbbítással.
Ez megkönnyíti és kevésbé bőbeszédűvé teszi a modulok között megosztott összetett parancssori argumentumokat.
Ezenkívül a könyvtár lehetővé teszi az argumentumok alapértelmezett értékeinek, leírásának és adattípusának meghatározását, így nincs szükség további ellenőrzésekre és átalakításokra.
from absl import flags
import sys
flags.DEFINE_string('name', 'User', 'The name of the user.')
FLAGS = flags.FLAGS
FLAGS(sys.argv)
print(f"Hello {FLAGS.name}!")
A támogatott adattípusok a következők:
DEFINE_integer()
DEFINE_string()
DEFINE_bool()
DEFINE_enum()
DEFINE_list()
DEFINE_float()
Szintén DEFINE_multi_integer()
, DEFINE_multi_string()
és a DEFINE_multi_enum()
több argumentumú bevitelhez. Ráadásul futás --help
, --helpfull
stb. kinyomtathatja a meglévő zászlókat és azok leírását, különböző formátumokban.
Tekintse meg gyakorlatias, gyakorlati útmutatónkat a Git tanulásához, amely tartalmazza a bevált gyakorlatokat, az iparág által elfogadott szabványokat és a mellékelt csalólapot. Hagyd abba a guglizást a Git parancsokkal, és valójában tanulni meg!
A könyvtár lehetővé teszi érvényesítések meghatározását is – mind a tartomány tekintetében, mint például az egész szám alapú értékek, amelyek upper_bound
or lower_bound
ez elfogadható, és tetszőleges módszerek futtatása az értékek ellenőrzésére:
def validate_name(value):
return len(value) > 15
flags.register_validator('name',
validate_name,
message='Name is over 15 characters long.',
flag_values=FLAGS)
Ezeket egy konkrét példába gyűjtve:
from absl import flags
import sys
flags.DEFINE_string('name', 'User', 'The name of the user.')
flags.DEFINE_integer('tasks', 0, 'The number of tasks a user has.', lower_bound=0)
FLAGS = flags.FLAGS
FLAGS(sys.argv)
print(f"{FLAGS.name} has {FLAGS.tasks} tasks to work on.")
$ python flags.py --name=John --tasks=5
John has 5 tasks to work on.
$ python flags.py --name=John --tasks=-1
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_flag.py", line 180, in _parse
return self.parser.parse(argument)
File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/site-packages/absl/flags/_argument_parser.py", line 168, in parse
raise ValueError('%s is not %s' % (val, self.syntactic_help))
ValueError: -1 is not a non-negative integer
...
Az argparse modul
A argparse modul a Python 3.2 óta elérhető, és a optparse
Python 2.7-ig létező modul. A Python dokumentációja tartalmaz egy API leírást és egy oktatóanyagot, amely részletesen lefedi az összes módszert.
A modul parancssori felületet kínál szabványos kimenettel, míg az előbbi két megoldás a munka nagy részét az Ön kezében hagyja. argparse
lehetővé teszi a rögzített és opcionális argumentumok ellenőrzését, a névellenőrzést akár rövid, akár hosszú stílusban. Alapértelmezett opcionális argumentumként tartalmazza -h
, annak hosszú változatával együtt --help
. Ezt az argumentumot egy alapértelmezett súgóüzenet kíséri, amely leírja az elfogadott argumentumokat.
Az alábbi kód az elemző inicializálását mutatja, az alábbi kimenet pedig az alaphívást, majd a súgó üzenetet. Az előző példákban használt Python-hívásokkal ellentétben ne feledje, hogy a Python 3-at használja ezekkel a példákkal:
import argparse
parser = argparse.ArgumentParser()
parser.parse_args()
$ python3 arguments-argparse-basic.py
$ python3 arguments-argparse-basic.py -h
usage: arguments-argparse-basic.py [-h]
optional arguments:
-h, --help show this help message and exit
$ python3 arguments-argparse-basic.py --verbose
usage: arguments-argparse-basic.py [-h]
arguments-argparse-basic.py: error: unrecognized arguments: --verbose
A következő lépésben egyéni leírást adunk a felhasználóinknak szóló súgóüzenethez. Az értelmező ilyen módon történő inicializálása további szöveget tesz lehetővé. Az alábbi kód a leírást a text
változó, amely kifejezetten a argparse
osztály, mint a description
paraméter. Az alábbi kód meghívásával láthatja, hogyan néz ki a kimenet:
import argparse
text = 'This is a test program. It demonstrates how to use the argparse module with a program description.'
parser = argparse.ArgumentParser(description=text)
parser.parse_args()
$ python3 arguments-argparse-description.py --help
usage: arguments-argparse-description.py [-h]
This is a test program. It demonstrates how to use the argparse module with a
program description.
optional arguments:
-h, --help show this help message and exit
Utolsó lépésként egy opcionális argumentumot adunk hozzá -V
, amelynek egy megfelelő hosszú stílusú argumentuma van --version
. Ehhez a módszert használjuk add_argument()
amelyet három paraméterrel hívunk meg (megjelenik a --version
, csak):
- A paraméter neve:
--version
- A paraméter súgószövege:
help="show program version"
- Művelet (kiegészítő érték nélkül):
action="store_true"
Ennek forráskódja az alábbiakban látható. Az argumentumok beolvasása a meghívott változóba args
keresztül történik parse_args()
módszer a parser
tárgy. Vegye figyelembe, hogy a rövid és a hosszú változatot is egy felhívásban küldje be. Végül ellenőrizze, hogy az attribútumok-e args.V
or args.version
be vannak állítva, és kiadják a verzióüzenetet:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-V", "--version", help="show program version", action="store_true")
args = parser.parse_args()
if args.version:
print("This is myprogram version 0.1")
$ python3 arguments-argparse-optional.py -V
This is myprogram version 0.1
$ python3 arguments-argparse-optional.py --version
This is myprogram version 0.1
A --version
argumentumhoz nem szükséges értéket megadni a parancssorban. Ezért állítjuk be a cselekvési argumentumot "store_true"
. Más esetekben szükség lehet egy további hozzárendelt értékre, például ha megad egy bizonyos térfogatot, magasságot vagy szélességet. Ez látható a következő példában. Alapértelmezett esetként vegye figyelembe, hogy az összes argumentum karakterláncként értelmeződik:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--width", "-w", help="set output width")
args = parser.parse_args()
if args.width:
print("Set output width to %s" % args.width)
Itt bemutatjuk, mi történik különböző argumentumértékek megadásakor. Ez magában foglalja mind a rövid, mind a hosszú verziót, valamint a súgó üzenetet:
$ python3 arguments-argparse-optional2.py -w 10
Set output width to 10
$ python3 arguments-argparse-optional2.py --width 10
Set output width to 10
$ python3 arguments-argparse-optional2.py -h
usage: arguments-argparse-optional2.py [-h] [--width WIDTH]
optional arguments:
-h, --help show this help message and exit
--width WIDTH, -w WIDTH
set output width
A getopt modul
Amint azt korábban észrevette, a sys
modul csak egyetlen oldalra osztja fel a parancssori karakterláncot. A Python getopt modul egy kicsit tovább megy, és kiterjeszti a bemeneti karakterlánc elválasztását a paraméterek érvényesítésével. Alapján getopt
C funkció, lehetővé teszi mind a rövid, mind a hosszú opciókat, beleértve az érték hozzárendelését.
A gyakorlatban megköveteli a sys
modult a bemeneti adatok megfelelő feldolgozásához. Ehhez mind a sys
modul és a getopt
A modult előre be kell tölteni. Ezután a bemeneti paraméterek listájából eltávolítjuk az első listaelemet (lásd az alábbi kódot), és a parancssori argumentumok fennmaradó listáját tároljuk az ún. argument_list
:
import getopt, sys
full_cmd_arguments = sys.argv
argument_list = full_cmd_arguments[1:]
print argument_list
Az érvek benne argument_list
most elemezni lehet a getopts()
módszer. De mielőtt ezt megtennénk, el kell mondanunk getopts()
arról, hogy mely paraméterek érvényesek. Ezeket így határozzák meg:
short_options = "ho:v"
long_options = ["help", "output=", "verbose"]
Ez azt jelenti, hogy ezek az érvek azok, amelyeket érvényesnek tartunk, néhány további információval együtt:
------------------------------------------
long argument short argument with value
------------------------------------------
--help -h no
--output -o yes
--verbose -v no
------------------------------------------
Talán észrevetted, hogy a o
A rövid opciót kettőspont követte, :
. Ez azt mondja getopt
hogy ehhez az opcióhoz értéket kell rendelni.
Ez most lehetővé teszi, hogy feldolgozzuk az érvek listáját. A getopt()
metódus három paramétert igényel – a tényleges argumentumok listáját argv
, valamint az érvényes rövid és hosszú opciókat is (az előző kódrészletben látható).
Maga a metódushívás try-catch-utasításban van tárolva, hogy fedezze a kiértékelés során előforduló hibákat. Kivételt jelent, ha a rendszer olyan argumentumot fedez fel, amely nem része a korábban meghatározott listának. A Python szkript kinyomtatja a hibaüzenetet a képernyőre, és kilép a 2-es hibakóddal:
try:
arguments, values = getopt.getopt(argument_list, short_options, long_options)
except getopt.error as err:
print (str(err))
sys.exit(2)
Végül a megfelelő értékekkel rendelkező argumentumok a két megnevezett változóban tárolódnak arguments
és a values
. Most már könnyedén kiértékelheti ezeket a változókat a kódjában. Használhatunk a for
-loop a felismert argumentumok listájának ismétléséhez, egyik bejegyzés a másik után.
for current_argument, current_value in arguments:
if current_argument in ("-v", "--verbose"):
print ("Enabling verbose mode")
elif current_argument in ("-h", "--help"):
print ("Displaying help")
elif current_argument in ("-o", "--output"):
print (("Enabling special output mode (%s)") % (current_value))
Az alábbiakban láthatja a kód végrehajtásának kimenetét. Megmutatjuk, hogyan reagál a program érvényes és érvénytelen program argumentumokkal:
$ python arguments-getopt.py -h
Displaying help
$ python arguments-getopt.py --help
Displaying help
$ python arguments-getopt.py --output=green --help -v
Enabling special output mode (green)
Displaying help
Enabling verbose mode
$ python arguments-getopt.py -verbose
option -e not recognized
A programunk utolsó hívása elsőre kissé zavarónak tűnhet. Ennek megértéséhez tudnia kell, hogy a gyorsírási opciók (néha zászlóknak is nevezik) egyetlen gondolatjellel együtt használhatók. Ez lehetővé teszi, hogy eszköze könnyebben elfogadjon számos lehetőséget. Például hívás python arguments-getopt.py -vh
ugyanaz, mint hívni python arguments-getopt.py -v -h
. Tehát a fenti utolsó hívásban a getopt
modul úgy gondolta, hogy a felhasználó megpróbált átadni -e
opcióként, ami érvénytelen.
Következtetés
Ebben a cikkben számos különböző módszert mutattunk be a parancssori argumentumok lekérésére a Pythonban, beleértve a használatát is sys
, getopt
és argparse
. Ezeknek a moduloknak a funkcionalitása különbözik, egyesek sokkal többet nyújtanak, mint mások. sys
teljesen rugalmas, míg mindkettő getopt
és a argparse
valamilyen struktúrát igényelnek. Ezzel szemben lefedik a legtöbb összetett munka, amely sys
rajtad múlik. A bemutatott példák átdolgozása után meg kell tudnia határozni, hogy melyik modul felel meg a legjobban projektjének.
Ebben a cikkben nem beszéltünk más megoldásokról, mint pl docopts
modult, most említettük. Ez a modul teljesen más megközelítést követ, és a következő cikkek egyikében részletesen ismertetjük.