Cum să analizați argumentele liniei de comandă în Python

Doriți să rulați scripturi Python cu argumente de linie de comandă? Aflați cum să analizați argumentele liniei de comandă folosind modulele sys, getopt și argparse în Python.

În Python, când doriți să citiți în intrarea utilizatorului, veți folosi funcția input(). Cu toate acestea, pentru unele aplicații, poate doriți să transmiteți anumite argumente în timp ce rulați scriptul la linia de comandă.

În acest tutorial, vom învăța cum să rulăm un script Python cu opțiuni și argumente la linia de comandă. Vom învăța apoi cum să folosim modulele încorporate din Python pentru a analiza astfel de opțiuni și argumente.

Sa incepem!

Înțelegerea sys.argv în Python

Dacă ați programat în C, știți că una dintre cele mai simple moduri de a transmite argumente programului este prin linia de comandă. Pentru a face acest lucru, puteți structura funcția principală astfel:

#include<stdio.h>

int main(int argc, char **argv){
    //argc: argument count
    //argv: argument vector
    
    //do something on the args

    return 0;
}

Aici, argc reprezintă numărul de argumente și argv reprezintă vectorul de argument.

Rularea scripturilor Python cu argumente din linia de comandă

În Python, puteți rula scriptul Python la linia de comandă folosind python3 filename.py. Când faceți acest lucru, puteți, de asemenea, să transmiteți un număr arbitrar de argumente de linie de comandă:

$ python3 filename.py arg1 arg2 ... argn

Modulul sys oferă asistență imediată pentru accesarea și procesarea acestor argumente din linia de comandă. sys.argv este lista tuturor argumentelor din linia de comandă pe care le transmitem atunci când rulăm scriptul Python.

Iată un exemplu în care rulăm main.py cu argumente de linie de comandă:

$ python3 main.py hello world python script

Putem parcurge vectorul argument folosind o funcție simplă pentru buclă și enumerare:

# 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

Vedem că primul argument (la indexul 0) este numele fișierului Python. Și argumentele ulterioare încep de la indexul 1.

Acesta este un program de lucru minim care acceptă și procesează argumentele liniei de comandă. Cu toate acestea, vedem câteva probleme:

  • Cum știu utilizatorii programului ce argumente să transmită?
  • Și ce înseamnă aceste argumente?

Acest lucru nu este foarte clar. Pentru a rezolva acest lucru, puteți utiliza fie modulele getopt, fie modulele argparse. Și vom afla asta în secțiunile următoare.✅

  11 platforme digitale de investiții imobiliare pentru investitori inteligenți

Analiza argumentelor din linia de comandă folosind getopt-ul Python

Să învățăm cum să analizăm argumentele liniei de comandă folosind modulul încorporat getopt.

După importarea getopt din modulul getopt, puteți specifica argumentele de analizat și opțiunile scurte și opțiunile lungi cu care rulați scriptul. Trebuie să analizăm toate argumentele începând cu indexul 1 în sys.argv. Deci felia de analizat este sys.argv[1:].

Aici, vom avea nevoie de un șir de mesaj și un nume de fișier. Să folosim m și f ca opțiuni scurte și mesaj și fișier ca opțiuni lungi.

Dar cum ne asigurăm că o anumită opțiune necesită un argument?

  • În opțiunile scurte, puteți face ca o opțiune să necesite un argument adăugând două puncte (:) după numele scurt al opțiunii.
  • În mod similar, în opțiunile lungi, puteți adăuga un semn = după opțiunea lungă. Putem surprinde aceste opțiuni și argumentele lor respective.

Adăugând acestea, vom avea următorul cod în main.py:

# main.py

import sys
from getopt import getopt

opts, args = getopt(sys.argv[1:],'m:f:',['message=","file="])

print(opts)
print(args)

Aici, variabila opts conține opțiunile și argumentele ca o listă de tupluri. Orice alt argument pozițional pe care îl transmitem va fi colectat în variabila args.

Putem transmite mesajul și numele fișierului pentru a rula scriptul și putem folosi fie opțiunile scurte, fie opțiunile lungi.

Rulând main.py folosind opțiunile lungi, avem:

$ python3 main.py --message hello --file somefile.txt

Avem opțiunile și argumentele ca tuple în variabila opts. Deoarece nu am trecut în niciun argument pozițional, args este o listă goală.

# Output
[("--message', 'hello'), ('--file', 'somefile.txt')]
[]

În mod echivalent, putem folosi și opțiunile scurte așa cum se arată:

$ python3 main.py -m hello -f somefile.txt
# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
[]

⚠️ Opțiunea scurtă -m din acest exemplu nu trebuie confundată cu flag-ul din linia de comandă -m care este folosit pentru a rula un modul ca modul principal atunci când rulează un script Python.

De exemplu, veți folosi python3 -m unittest main.py pentru a rula unittest ca modul principal atunci când rulați main.py.

Am menționat că toate celelalte argumente poziționale pe care le transmitem vor fi colectate în variabila args. Iată un exemplu:

$ python3 main.py -m hello -f somefile.txt another_argument

Lista de argumente conține argumentul pozițional another_argument.

# Output
[('-m', 'hello'), ('-f', 'somefile.txt')]
['another_argument']

Aici, opts este o listă de tupluri. Așa că putem trece prin el, despachetăm tuplu și scoatem argumentele corespunzătoare opțiunilor specifice.

Dar ce facem cu numele fișierului și mesajul după ce am procesat aceste argumente? Vom deschide fișierul în modul de scriere și vom scrie șirul de mesaj convertit în majuscule în fișier.

# 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())

Să rulăm main.py cu opțiunile scurte și argumentele liniei de comandă.

$ python main.py -m hello -f thisfile.txt
[('-m', 'hello'), ('-f', 'thisfile.txt')]
[]

După rularea main.py, putem vedea „thisfile.txt” în directorul nostru de lucru. Conține șirul „hello” convertit în majuscule („HELLO”).

$ ls
main.py  thisfile.txt
$ cat thisfile.txt
HELLO

Cum să analizați argumentele din linia de comandă cu Argparse

Modulul argparse, de asemenea, încorporat în biblioteca standard Python, oferă funcționalitate pentru a analiza argumentele din linia de comandă și, de asemenea, pentru a construi interfețe pentru linia de comandă.

  De ce scrie Așteptați plata pe G2A?

Pentru a analiza argumentele liniei de comandă, să importăm clasa ArgumentParser din modulul argparse. Aici, am instanțiat arg_parser, un obiect ArgumentParser:

from argparse import ArgumentParser

arg_parser = ArgumentParser()

În continuare, am dori să adăugăm două argumente de linie de comandă:

  • mesaj: șirul mesajului și
  • fișier: numele fișierului cu care dorim să lucrăm.

Acum apelăm metoda add_argument() pe arg_parser pentru a adăuga aceste argumente. În apelul metodei add_argument(), puteți seta ajutor la un șir (o descriere a argumentului).

arg_parser.add_argument('message',help='message string')
arg_parser.add_argument('file',help='filename')

Până acum, am instanțiat arg_parser și am adăugat argumentele liniei de comandă. Când programul este rulat la linia de comandă, puteți folosi metoda parse_args() pe arg_parser pentru a obține valorile argumentelor.

Aici, capturăm spațiul de nume argument în variabila args. Deci puteți folosi args.argument_name pentru a obține valorile argumentelor.

După ce obținem valorile argumentelor, scriem șirul de mesaj cu majuscule schimbate (folosind metoda șirurilor swapcase()) în fișier.

args = arg_parser.parse_args()

message = args.message
file = args.file

with open(file,'w') as f:
     f.write(message.swapcase())

Punând totul împreună, iată fișierul nostru 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())

Înțelegerea utilizării argumentelor din linia de comandă

Pentru a înțelege utilizarea argumentelor atunci când rulați main.py, puteți utiliza opțiunea –help long, așa cum se arată:

$ 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

Nu există argumente opționale și atât mesajul, cât și fișierul sunt argumente poziționale necesare. Alternativ, puteți utiliza și opțiunea scurtă -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

După cum s-a văzut, ambele argumente sunt argumente poziționale în mod implicit. Deci, dacă nu introduceți unul sau mai multe dintre aceste argumente, veți întâlni erori.

Aici, am trecut un argument pozițional (Bună ziua) pentru șirul de mesaj, dar nu am furnizat nicio valoare pentru argumentul fișierului.

Și obținem o eroare care declară că argumentul fișierului este necesar.

$ python3 main.py Hello
usage: main.py [-h] message file
main.py: error: the following arguments are required: file

Când rulăm main.py cu ambele argumente poziționale, vedem că args spațiului de nume conține valorile argumentelor.

$ python3 main.py Hello file1.txt
# Output
Namespace(file="file1.txt", message="Hello")

Acum, dacă examinăm conținutul directorului de lucru prezent, vedem că scriptul creează fișierul „fișier1.txt”:

$ ls
file1.txt  main.py

Șirul de mesaj original este „Bună ziua”; după schimbarea majusculei, șirul de mesaj din fișierul „fișier1.txt” este „salut”.

$ cat file1.txt
hELLO

Cum să faceți opționale argumentele din linia de comandă

Pentru a face aceste argumente din linia de comandă opționale, puteți prefix numele argumentului cu –.

  Cu Sachin Arya (CEO-ul BITS Pilani Incubation)

Să modificăm main.py pentru a face atât mesajul, cât și argumentele fișierului opționale.

# main.py

from argparse import ArgumentParser

arg_parser = ArgumentParser()
arg_parser.add_argument('--message',help='message string')
arg_parser.add_argument('--file',help='filename')

Deoarece argumentele liniei de comandă sunt ambele opționale, putem seta valori implicite pentru aceste argumente.

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='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())

Dacă verificăm utilizarea, vedem că atât mesajul, cât și fișierul sunt argumente opționale. Înseamnă că acum puteți rula main.py fără ambele argumente.

$ 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

În spațiul de nume argument, atât fișierul, cât și mesajul sunt Nici unul.

# Output
Namespace(file=None, message=None)

Vedem că numele și mesajul implicit „fișierul meu.txt” și „Python3” sunt folosite. Fișierul „myfile.txt” se află acum în directorul de lucru:

$ ls
file1.txt  main.py  myfile.txt

Și conține șirul „Python3” cu majusculele literelor schimbate:

$ cat myfile.txt
pYTHON3

De asemenea, puteți utiliza atât argumentele –message cât și –file pentru a face comanda mai lizibilă.

$ python3 main.py --message Coding --file file2.txt
# Output
Namespace(file="file2.txt", message="Coding")

Vedem „fișier2.txt” în directorul de lucru:

$ ls
file1.txt  file2.txt  main.py  myfile.txt

Și conține șirul „coding” așa cum era de așteptat.

$ cat file2.txt
cODING

Concluzie

Iată un rezumat a ceea ce am învățat în acest tutorial:

  • Similar cu limbajul de programare C, în Python, puteți accesa argumentele liniei de comandă prin bucla prin vectorul de argument sys.argv. sys.argv[0] este numele scriptului Python. Deci suntem interesați să analizăm argumentele sys.argv[1:].
  • Cu toate acestea, pentru a îmbunătăți lizibilitatea și pentru a putea adăuga opțiuni, puteți utiliza modulele getopt și argparse.
  • Puteți utiliza modulul getopt pentru a analiza lista de argumente ale liniei de comandă începând cu indexul 1 până la sfârșitul listei. Puteți specifica atât opțiuni scurte, cât și opțiuni lungi.
  • Când o opțiune preia un argument, puteți specifica două puncte (:) și = după opțiunea scurtă și, respectiv, opțiunea lungă.
  • Cu modulul argparse al lui Python, puteți instanția un obiect ArgumentParser și puteți utiliza metoda add_argument() pentru a adăuga un argument pozițional necesar. Utilizați — înainte de numele argumentului pentru a-l face opțional.
  • Pentru a prelua valorile argumentelor liniei de comandă, apelați metoda parse_args() de pe obiectul ArgumentParser.

Apoi, aflați cum să efectuați hashing securizat în Python.