Te întrebi cum să execuți scripturi Python folosind argumente în linia de comandă? Descoperă cum să interpretezi aceste argumente cu ajutorul modulelor sys, getopt și argparse din Python.
În mod obișnuit, când dorești să primești date de la utilizator în Python, apelezi la funcția `input()`. Totuși, în anumite scenarii, poate fi necesar să transmiți direct argumente în momentul executării scriptului, prin intermediul liniei de comandă.
Acest ghid îți va arăta cum să rulezi un script Python cu diverse opțiuni și argumente, direct din linia de comandă. Vei învăța să utilizezi modulele predefinite ale Python pentru a analiza aceste opțiuni și argumente.
Să începem!
Explorând `sys.argv` în Python
Dacă ai experiență cu limbajul C, știi că un mod simplu de a trimite argumente unui program este prin intermediul liniei de comandă. În C, poți organiza funcția principală astfel:
#include<stdio.h> int main(int argc, char **argv){ //argc: numărul de argumente //argv: vectorul de argumente //prelucrează argumentele aici return 0; }
Aici, `argc` reține numărul de argumente transmise, iar `argv` este un vector care le stochează.
Executarea scripturilor Python cu argumente din linia de comandă
În Python, pentru a rula un script, folosești comanda `python3 filename.py`. Odată cu aceasta, poți adăuga un număr variabil de argumente din linia de comandă:
$ python3 filename.py arg1 arg2 ... argn
Modulul `sys` oferă instrumente pentru a accesa și gestiona aceste argumente. `sys.argv` este o listă care include toate argumentele transmise la rularea scriptului Python.
Un exemplu de rulare a `main.py` cu argumente din linia de comandă:
$ python3 main.py hello world python script
Putem itera prin vectorul de argumente folosind o buclă simplă și funcția `enumerate`:
# main.py import sys for idx, arg in enumerate(sys.argv): print(f"arg{idx}: {arg}")
# Ieșire arg0:main.py arg1:hello arg2:world arg3:python arg4:script
Observăm că primul argument (indexul 0) este numele fișierului Python, iar argumentele ulterioare încep de la indexul 1.
Acesta este un program de bază care primește și prelucrează argumentele liniei de comandă. Însă, apar câteva neclarități:
- Cum știu utilizatorii ce argumente să introducă?
- Ce reprezintă exact aceste argumente?
Pentru a clarifica aceste aspecte, poți folosi modulele `getopt` sau `argparse`. În secțiunile următoare, vom explora aceste module.✅
Analiza argumentelor liniei de comandă cu `getopt` în Python
Vom învăța cum să interpretăm argumentele liniei de comandă folosind modulul `getopt` inclus în Python.
După ce importăm modulul `getopt`, putem specifica argumentele de analizat, opțiunile scurte și opțiunile lungi. Este necesar să analizăm argumentele începând cu indexul 1 din `sys.argv`. Astfel, porțiunea de analizat este `sys.argv[1:]`.
Pentru exemplificare, vom avea nevoie de un mesaj și un nume de fișier. Vom folosi `m` și `f` ca opțiuni scurte, iar `message` și `file` ca opțiuni lungi.
Cum ne asigurăm că o anumită opțiune necesită un argument?
- Pentru opțiunile scurte, adaugă două puncte (:) după numele scurt al opțiunii.
- Similar, pentru opțiunile lungi, adaugă semnul = după opțiunea lungă. Astfel, putem capta aceste opțiuni și argumentele asociate.
Cu aceste adăugiri, codul din `main.py` va arăta astfel:
# main.py import sys from getopt import getopt opts, args = getopt(sys.argv[1:],'m:f:',['message=','file=']) print(opts) print(args)
În acest cod, variabila `opts` va reține opțiunile și argumentele ca o listă de tupluri. Orice alt argument pozițional transmis va fi stocat în variabila `args`.
Putem trimite mesajul și numele fișierului la rularea scriptului, folosind fie opțiunile scurte, fie cele lungi.
Iată cum arată executarea `main.py` folosind opțiunile lungi:
$ python3 main.py --message hello --file somefile.txt
Opțiunile și argumentele sunt stocate ca tupluri în variabila `opts`. Deoarece nu am introdus argumente poziționale, `args` va fi o listă goală.
# Ieșire [('--message', 'hello'), ('--file', 'somefile.txt')] []
În mod similar, putem folosi opțiunile scurte, după cum urmează:
$ python3 main.py -m hello -f somefile.txt
# Ieșire [('-m', 'hello'), ('-f', 'somefile.txt')] []
⚠️ Opțiunea scurtă `-m` din acest exemplu nu trebuie confundată cu indicatorul liniei de comandă `-m`, care rulează un modul ca modul principal la executarea scriptului Python.
De exemplu, `python3 -m unittest main.py` rulează `unittest` ca modul principal când execuți `main.py`.
Am menționat că orice alte argumente poziționale sunt stocate în variabila `args`. Iată un exemplu:
$ python3 main.py -m hello -f somefile.txt another_argument
Lista de argumente include argumentul pozițional `another_argument`.
# Ieșire [('-m', 'hello'), ('-f', 'somefile.txt')] ['another_argument']
Având `opts` ca o listă de tupluri, putem itera prin ea, despachetând fiecare tuplu pentru a extrage argumentele asociate opțiunilor respective.
Ce facem cu numele fișierului și mesajul, odată ce le-am preluat? Vom deschide fișierul în modul scriere și vom adăuga mesajul transformat în majuscule.
# 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())
Rulăm `main.py` cu opțiunile scurte și argumentele din linia de comandă.
$ python main.py -m hello -f thisfile.txt [('-m', 'hello'), ('-f', 'thisfile.txt')] []
După executarea `main.py`, vom observa `thisfile.txt` în directorul curent. Acesta conține mesajul „hello” transformat în majuscule („HELLO”).
$ ls main.py thisfile.txt
$ cat thisfile.txt HELLO
Analizarea argumentelor liniei de comandă cu Argparse
Modulul `argparse`, inclus în biblioteca standard Python, oferă funcționalități pentru analiza argumentelor liniei de comandă și construirea interfețelor pentru aceasta.
Pentru analiza argumentelor liniei de comandă, importăm clasa `ArgumentParser` din modulul `argparse`. Aici, am creat o instanță `arg_parser`, un obiect `ArgumentParser`:
from argparse import ArgumentParser arg_parser = ArgumentParser()
Apoi, dorim să adăugăm două argumente din linia de comandă:
- `message`: șirul de mesaj și
- `file`: numele fișierului cu care lucrăm.
Apelăm metoda `add_argument()` pe `arg_parser` pentru a adăuga aceste argumente. În cadrul apelului, poți stabili un șir de ajutor (o descriere a argumentului) cu parametrul `help`.
arg_parser.add_argument('message',help='șir de mesaj') arg_parser.add_argument('file',help='nume fișier')
Până acum, am instanțiat `arg_parser` și am adăugat argumentele liniei de comandă. Când programul este executat, poți folosi metoda `parse_args()` pe `arg_parser` pentru a prelua valorile argumentelor.
Aici, stocăm spațiul de nume al argumentelor în variabila `args`. Astfel, poți utiliza `args.nume_argument` pentru a obține valorile argumentelor.
După ce obținem valorile argumentelor, scriem șirul de mesaj cu majuscule și minuscule inversate (folosind metoda `swapcase()` a șirurilor) în fișier.
args = arg_parser.parse_args() message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Reunind totul, iată conținutul fișierului `main.py`:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('message',help='șir de mesaj') arg_parser.add_argument('file',help='nume fișier') args = arg_parser.parse_args() print(args) message = args.message file = args.file with open(file,'w') as f: f.write(message.swapcase())
Înțelegerea utilizării argumentelor liniei de comandă
Pentru a înțelege cum să folosești argumentele când rulezi `main.py`, folosește opțiunea `–help` (lungă), după cum urmează:
$ python3 main.py --help usage: main.py [-h] message file positional arguments: message șir de mesaj file nume fișier optional arguments: -h, --help afişează acest mesaj de ajutor şi iese
Nu există argumente opționale, iar `message` și `file` sunt argumente poziționale obligatorii. Alternativ, poți folosi opțiunea scurtă `-h`:
$ python3 main.py -h usage: main.py [-h] message file positional arguments: message șir de mesaj file nume fișier optional arguments: -h, --help afişează acest mesaj de ajutor şi iese
Așa cum se observă, ambele argumente sunt implicit poziționale. Dacă nu introduci unul sau ambele argumente, vei întâmpina erori.
Aici, am transmis un argument pozițional („Bună ziua”) pentru șirul de mesaj, dar nu am oferit nicio valoare pentru argumentul fișierului.
Eroarea indică faptul că argumentul fișierului este necesar.
$ python3 main.py Bună ziua usage: main.py [-h] message file main.py: error: the following arguments are required: file
Când executăm `main.py` cu ambele argumente poziționale, vedem că spațiul de nume `args` conține valorile argumentelor.
$ python3 main.py Bună ziua file1.txt
# Ieșire Namespace(file="file1.txt", message="Bună ziua")
Examinând conținutul directorului de lucru, observăm că scriptul creează fișierul `file1.txt`:
$ ls file1.txt main.py
Șirul de mesaj original este „Bună ziua”; după inversarea majusculelor și minusculor, conținutul fișierului `file1.txt` este „bUNĂ zIUA”.
$ cat file1.txt bUNĂ zIUA
Cum să faci opționale argumentele liniei de comandă
Pentru a face argumentele opționale, adaugă un prefix „–” la numele argumentului.
Să modificăm `main.py` pentru a face atât argumentul `message`, cât și argumentul `file` opționale.
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='șir de mesaj') arg_parser.add_argument('--file',help='nume fișier')
Întrucât argumentele liniei de comandă sunt acum opționale, putem stabili valori implicite pentru acestea.
if args.message and args.file: message = args.message file = args.file else: message="Python3" file="myfile.txt"
În acest moment, fișierul `main.py` conține următorul cod:
# main.py from argparse import ArgumentParser arg_parser = ArgumentParser() arg_parser.add_argument('--message',help='șir de mesaj') arg_parser.add_argument('--file',help='nume fișier') 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())
Dacă verificăm utilizarea, vom observa că ambele argumente sunt opționale. Astfel, poți rula `main.py` fără să oferi niciunul dintre argumente.
$ python3 main.py --help usage: main.py [-h] [--message MESSAGE] [--file FILE] optional arguments: -h, --help afişează acest mesaj de ajutor şi iese --message MESSAGE șir de mesaj --file FILE nume fișier
$ python3 main.py
În spațiul de nume al argumentelor, ambele valori pentru `file` și `message` sunt `None`.
# Ieșire Namespace(file=None, message=None)
Observăm că se utilizează numele implicit al fișierului, „myfile.txt”, și mesajul implicit „Python3”. Fișierul „myfile.txt” este acum prezent în directorul de lucru:
$ ls file1.txt main.py myfile.txt
Și conține șirul „Python3” cu majusculele și minusculele inversate:
$ cat myfile.txt pYTHON3
Poți folosi argumentele `–message` și `–file` pentru a face comanda mai clară.
$ python3 main.py --message Coding --file file2.txt
# Ieșire Namespace(file="file2.txt", message="Coding")
Observăm `file2.txt` în directorul de lucru:
$ ls file1.txt file2.txt main.py myfile.txt
Și conține șirul „coding”, așa cum ne-am așteptat.
$ cat file2.txt cODING
Concluzie
Iată un rezumat al aspectelor învățate în acest ghid:
- Similar limbajului C, în Python, poți accesa argumentele din linia de comandă iterând prin vectorul de argumente `sys.argv`. `sys.argv[0]` este numele scriptului Python. De aceea, ne concentrăm pe analiza argumentelor din `sys.argv[1:]`.
- Pentru a îmbunătăți lizibilitatea și pentru a adăuga opțiuni, folosește modulele `getopt` și `argparse`.
- Modulul `getopt` analizează lista de argumente din linia de comandă începând de la indexul 1 până la final. Poți defini atât opțiuni scurte, cât și lungi.
- Când o opțiune necesită un argument, specifică două puncte (:) și, respectiv, egal (=) după opțiunea scurtă și lungă.
- Cu modulul `argparse` din Python, poți crea un obiect `ArgumentParser` și folosi metoda `add_argument()` pentru a adăuga un argument pozițional obligatoriu. Folosește prefixul „–” în fața numelui argumentului pentru a-l face opțional.
- Pentru a prelua valorile argumentelor din linia de comandă, apelează metoda `parse_args()` a obiectului `ArgumentParser`.
În continuare, explorează cum să efectuezi hashing securizat în Python.