Sådan parses kommandolinjeargumenter i Python

Vil du køre Python-scripts med kommandolinjeargumenter? Lær, hvordan du parser kommandolinjeargumenter ved hjælp af sys-, getopt- og argparse-moduler i Python.

I Python, når du vil læse brugerinput, skal du bruge input()-funktionen. Men for nogle applikationer vil du måske sende visse argumenter ind, mens du kører scriptet på kommandolinjen.

I denne tutorial lærer vi, hvordan du kører et Python-script med muligheder og argumenter på kommandolinjen. Vi lærer derefter, hvordan man bruger Pythons indbyggede moduler til at analysere sådanne muligheder og argumenter.

Lad os begynde!

Forståelse af sys.argv i Python

Hvis du har programmeret i C, ved du, at en af ​​de enkleste måder at sende argumenter til programmet på er via kommandolinjen. For at gøre det kan du strukturere hovedfunktionen sådan:

#include<stdio.h>

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

    return 0;
}

Her står argc for argumentantal og argv står for argumentvektor.

Kørsel af Python-scripts med kommandolinjeargumenter

I Python kan du køre Python-scriptet på kommandolinjen ved hjælp af python3 filnavn.py. Når du gør det, kan du også sende et vilkårligt antal kommandolinjeargumenter:

$ python3 filename.py arg1 arg2 ... argn

Sys-modulet giver klar support til at få adgang til og behandle disse kommandolinjeargumenter. sys.argv er listen over alle de kommandolinjeargumenter, som vi sender ind, når vi kører Python-scriptet.

Her er et eksempel, hvor vi kører main.py med kommandolinjeargumenter:

$ python3 main.py hello world python script

Vi kan sløjfe gennem argumentvektoren ved at bruge en simpel for-løkke- og enumerate-funktion:

# 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

Vi ser, at det første argument (ved indeks 0) er navnet på Python-filen. Og efterfølgende argumenter starter ved indeks 1.

Dette er et minimalt arbejdsprogram, der accepterer og behandler kommandolinjeargumenter. Vi ser dog nogle problemer:

  • Hvordan ved brugere af programmet, hvilke argumenter de skal sende ind?
  • Og hvad står disse argumenter for?

Dette er ikke særlig klart. For at løse dette kan du bruge enten getopt- eller argparse-modulerne. Og det lærer vi i de næste afsnit.✅

Kommandolinje-argumentparsing ved hjælp af Pythons getopt

Lad os lære, hvordan man analyserer kommandolinjeargumenter ved hjælp af det indbyggede getopt-modul.

Efter at have importeret getopt fra getopt-modulet, kan du angive de argumenter, der skal parses, og de korte muligheder og lange muligheder for at køre scriptet med. Vi skal parse alle argumenter, der starter ved indeks 1 i sys.argv. Så det udsnit, der skal parses, er sys.argv[1:].

  Sådan ser du et skjult "snydeark" med tastaturgenveje på iPad

Her skal vi bruge en meddelelsesstreng og filnavn. Lad os bruge m og f som korte muligheder og besked og fil som lange muligheder.

Men hvordan sikrer vi, at en bestemt mulighed kræver et argument?

  • I korte indstillinger kan du få en indstilling til at kræve et argument ved at tilføje et kolon (:) efter det korte valgnavn.
  • På samme måde kan du i lange muligheder tilføje et =-tegn efter den lange mulighed. Vi kan fange disse muligheder og deres respektive argumenter.

Hvis du tilføjer disse, har vi følgende kode i main.py:

# main.py

import sys
from getopt import getopt

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

print(opts)
print(args)

Her indeholder variablen opts mulighederne og argumenterne som en liste over tupler. Ethvert andet positionsargument, som vi sender ind, vil blive samlet i args-variablen.

Vi kan sende beskeden og filnavnet ind for at køre scriptet, og vi kan bruge enten de korte eller lange muligheder.

Når vi kører main.py ved hjælp af de lange muligheder, har vi:

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

Vi har mulighederne og argumenterne som tuples i opts-variablen. Da vi ikke har bestået noget positionelt argument, er args en tom liste.

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

Tilsvarende kan vi også bruge de korte muligheder som vist:

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

⚠️ Den korte -m-indstilling i dette eksempel skal ikke forveksles med kommandolinjeflaget -m, som bruges til at køre et modul som hovedmodul, når der køres et Python-script.

For eksempel vil du bruge python3 -m unittest main.py til at køre unittest som hovedmodulet, når du kører main.py.

Vi nævnte, at alle andre positionsargumenter, som vi sender ind, vil blive samlet i args-variablen. Her er et eksempel:

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

Argumentlisten indeholder positionsargumentet another_argument.

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

Her er opts en liste over tupler. Så vi kan gå igennem det, pakke tuplet ud og trække argumenterne ud, der svarer til de specifikke muligheder.

Men hvad gør vi med filnavnet og beskeden, efter at vi har behandlet disse argumenter? Vi åbner filen i skrivetilstand og skriver meddelelsesstrengen konverteret til store bogstaver til filen.

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

Lad os køre main.py med de korte muligheder og kommandolinjeargumenter.

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

Efter at have kørt main.py, kan vi se ‘thisfile.txt’ i vores arbejdsmappe. Den indeholder strengen ‘hello’ konverteret til store bogstaver (‘HELLO’).

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

Sådan parses kommandolinjeargumenter med Argparse

Argparse-modulet, der også er indbygget i Python-standardbiblioteket, giver funktionalitet til at parse kommandolinjeargumenter og også bygge kommandolinjegrænseflader.

  10 Bogoversigt Apps til at optimere din læsning

For at parse kommandolinjeargumenter, lad os importere ArgumentParser-klassen fra argparse-modulet. Her har vi instantieret arg_parser, et ArgumentParser-objekt:

from argparse import ArgumentParser

arg_parser = ArgumentParser()

Dernæst vil vi gerne tilføje to kommandolinjeargumenter:

  • besked: beskedstrengen og
  • fil: navnet på den fil, vi gerne vil arbejde med.

Nu kalder vi add_argument()-metoden på arg_parser for at tilføje begge disse argumenter. I add_argument() metodekaldet kan du sætte hjælp til en streng (en beskrivelse af argumentet).

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

Indtil videre har vi instantieret arg_parser og tilføjet kommandolinjeargumenterne. Når programmet køres på kommandolinjen, kan du bruge metoden parse_args() på arg_parser for at få værdierne af argumenterne.

Her fanger vi argumentnavnerummet i variablen args. Så du kan bruge args.argument_name til at få værdierne af argumenterne.

Efter at have fået værdierne af argumenterne, skriver vi meddelelsesstrengen med case swapped (ved hjælp af swapcase() strengmetoden) til filen.

args = arg_parser.parse_args()

message = args.message
file = args.file

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

Sætter det hele sammen, her er vores main.py-fil:

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

Forstå kommandolinjeargumentbrug

For at forstå brugen af ​​argumenterne, når du kører main.py, kan du bruge –help long-indstillingen som vist:

$ 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

Der er ingen valgfri argumenter, og både besked og fil er påkrævede positionsargumenter. Alternativt kan du også bruge den korte mulighed -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

Som det ses, er begge argumenter positionelle argumenter som standard. Så hvis du ikke videregiver et eller flere af disse argumenter, vil du løbe ind i fejl.

Her har vi indsendt et positionsargument (Hej) for meddelelsesstrengen, men vi har ikke angivet nogen værdi for filargumentet.

Og vi får en fejl om, at filargumentet er påkrævet.

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

Når vi kører main.py med begge positionsargumenter, ser vi, at navnerummet args indeholder værdierne af argumenterne.

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

Hvis vi nu undersøger indholdet af den nuværende arbejdsmappe, ser vi, at scriptet opretter filen ‘file1.txt’:

$ ls
file1.txt  main.py

Den oprindelige meddelelsesstreng er ‘Hej’; efter at have byttet sagen er beskedstrengen i filen ‘fil1.txt’ ‘HEJ’.

$ cat file1.txt
hELLO

Sådan gør du kommandolinjeargumenter valgfrie

For at gøre disse kommandolinjeargumenter valgfrie, kan du præfikse argumentnavnet med –.

  Sådan får du et billede bag tekst i PowerPoint

Lad os ændre main.py for at gøre både meddelelsen og filargumenterne valgfrie.

# main.py

from argparse import ArgumentParser

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

Da kommandolinjeargumenterne begge er valgfrie, kan vi indstille standardværdier for disse argumenter.

if args.message and args.file:
    message = args.message
    file = args.file
else:
    message="Python3"
    file="myfile.txt"

På dette tidspunkt indeholder main.py-filen følgende kode:

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

Hvis vi tjekker brugen, ser vi, at både besked og fil er valgfrie argumenter. Det betyder, at du nu kan køre main.py uden begge disse argumenter.

$ 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

I argumentnavnerummet er både fil og besked Ingen.

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

Vi ser, at standardfilnavnet og beskeden ‘myfile.txt’ og ‘Python3’ er brugt. Filen ‘myfile.txt’ er nu i arbejdsmappen:

$ ls
file1.txt  main.py  myfile.txt

Og den indeholder strengen ‘Python3’ med store og små bogstaver ombyttet:

$ cat myfile.txt
pYTHON3

Du kan også bruge både –message og –file argumenterne for at gøre kommandoen mere læsbar.

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

Vi ser ‘file2.txt’ i arbejdsmappen:

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

Og den indeholder strengen ‘coDING’ som forventet.

$ cat file2.txt
cODING

Konklusion

Her er en oversigt over, hvad vi har lært i denne øvelse:

  • I lighed med programmeringssproget C kan du i Python få adgang til kommandolinjeargumenterne ved at gå gennem argumentvektoren sys.argv. sys.argv[0] er navnet på Python-scriptet. Så vi er interesserede i at analysere argumenterne sys.argv[1:].
  • Men for at forbedre læsbarheden og for at kunne tilføje muligheder, kan du bruge til at få opt og argparse moduler.
  • Du kan bruge getopt-modulet til at parse listen over kommandolinjeargumenter, der starter ved indeks 1 op til slutningen af ​​listen. Du kan angive både korte og lange tilvalg.
  • Når en indstilling tager et argument, kan du angive et kolon (:) og = efter henholdsvis den korte indstilling og den lange indstilling.
  • Med Pythons argparse-modul kan du instansiere et ArgumentParser-objekt og bruge add_argument()-metoden til at tilføje et påkrævet positionsargument. Brug — før argumentnavnet for at gøre det valgfrit.
  • For at hente værdierne af kommandolinjeargumenterne skal du kalde metoden parse_args() på ArgumentParser-objektet.

Lær derefter, hvordan du udfører sikker hashing i Python.