Hur man analyserar kommandoradsargument i Python

Vill du köra Python-skript med kommandoradsargument? Lär dig hur du analyserar kommandoradsargument med sys-, getopt- och argparse-moduler i Python.

I Python, när du vill läsa in användarinmatning, använder du input()-funktionen. Men för vissa program kanske du vill skicka in vissa argument medan du kör skriptet på kommandoraden.

I den här handledningen kommer vi att lära oss hur man kör ett Python-skript med alternativ och argument på kommandoraden. Vi kommer sedan att lära oss hur man använder Pythons inbyggda moduler för att analysera sådana alternativ och argument.

Låt oss börja!

Förstå sys.argv i Python

Om du har programmerat i C vet du att ett av de enklaste sätten att skicka in argument till programmet är via kommandoraden. För att göra det kan du strukturera huvudfunktionen så här:

#include<stdio.h>

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

    return 0;
}

Här står argc för argumentantal och argv står för argumentvektor.

Köra Python-skript med kommandoradsargument

I Python kan du köra Python-skriptet på kommandoraden med python3 filnamn.py. När du gör det kan du också skicka in ett godtyckligt antal kommandoradsargument:

$ python3 filename.py arg1 arg2 ... argn

Sys-modulen ger direkt support för att komma åt och bearbeta dessa kommandoradsargument. sys.argv är listan över alla kommandoradsargument som vi skickar in när vi kör Python-skriptet.

Här är ett exempel där vi kör main.py med kommandoradsargument:

$ python3 main.py hello world python script

Vi kan loopa igenom argumentvektorn med en enkel för loop och 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 att det första argumentet (vid index 0) är namnet på Python-filen. Och efterföljande argument börjar vid index 1.

Detta är ett minimalt fungerande program som accepterar och bearbetar kommandoradsargument. Men vi ser några problem:

  • Hur vet användarna av programmet vilka argument som ska skickas in?
  • Och vad står dessa argument för?

Detta är inte särskilt tydligt. För att hantera detta kan du använda antingen getopt- eller argparse-modulerna. Och det lär vi oss i nästa avsnitt.✅

Kommandoradsargumentanalys med Pythons getopt

Låt oss lära oss hur man analyserar kommandoradsargument med den inbyggda getopt-modulen.

Efter att ha importerat getopt från getopt-modulen kan du ange argumenten som ska analyseras och de korta alternativen och långa alternativen att köra skriptet med. Vi måste analysera alla argument som börjar vid index 1 i sys.argv. Så segmentet att analysera är sys.argv[1:].

Här behöver vi en meddelandesträng och filnamn. Låt oss använda m och f som korta alternativ och meddelande och fil som långa alternativ.

Men hur säkerställer vi att ett specifikt alternativ kräver ett argument?

  • I korta alternativ kan du göra att ett alternativ kräver ett argument genom att lägga till ett kolon (:) efter det korta alternativets namn.
  • På samma sätt, i långa alternativ, kan du lägga till ett =-tecken efter det långa alternativet. Vi kan fånga dessa alternativ och deras respektive argument.

Om du lägger till dessa kommer vi att ha följande kod 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)

Här innehåller variabeln opts alternativen och argumenten som en lista över tupler. Alla andra positionsargument som vi skickar in kommer att samlas i variabeln args.

Vi kan skicka in meddelandet och filnamnet för att köra skriptet, och vi kan använda antingen de korta alternativen eller de långa alternativen.

Genom att köra main.py med de långa alternativen har vi:

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

Vi har alternativen och argumenten som tupler i variabeln opts. Eftersom vi inte har gått igenom något positionsargument är args en tom lista.

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

På motsvarande sätt kan vi också använda de korta alternativen som visas:

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

⚠️ Det korta alternativet -m i det här exemplet ska inte förväxlas med kommandoradsflaggan -m som används för att köra en modul som huvudmodul när man kör ett Python-skript.

Till exempel kommer du att använda python3 -m unittest main.py för att köra unittest som huvudmodul när du kör main.py.

Vi nämnde att alla andra positionsargument som vi skickar in kommer att samlas i variabeln args. Här är ett exempel:

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

Argumentlistan innehåller positionsargumentet another_argument.

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

Här är opts en lista över tupler. Så vi kan gå igenom den, packa upp tupeln och dra ut argumenten som motsvarar de specifika alternativen.

Men vad gör vi med filnamnet och meddelandet efter att vi har bearbetat dessa argument? Vi öppnar filen i skrivläge och skriver meddelandesträngen som konverterats till versaler till 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())

Låt oss köra main.py med de korta alternativen och kommandoradsargumenten.

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

Efter att ha kört main.py kan vi se ’thisfile.txt’ i vår arbetskatalog. Den innehåller strängen ’hej’ omvandlad till versaler (’HELLO’).

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

Hur man analyserar kommandoradsargument med Argparse

Argparse-modulen, även inbyggd i Python-standardbiblioteket, tillhandahåller funktionalitet för att analysera kommandoradsargument och även bygga kommandoradsgränssnitt.

För att analysera kommandoradsargument, låt oss importera ArgumentParser-klassen från argparse-modulen. Här har vi instansierat arg_parser, ett ArgumentParser-objekt:

from argparse import ArgumentParser

arg_parser = ArgumentParser()

Därefter vill vi lägga till två kommandoradsargument:

  • meddelande: meddelandesträngen och
  • fil: namnet på filen vi vill arbeta med.

Nu anropar vi add_argument()-metoden på arg_parser för att lägga till båda dessa argument. I metodanropet add_argument() kan du ställa in hjälp till en sträng (en beskrivning av argumentet).

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

Hittills har vi instansierat arg_parser och lagt till kommandoradsargumenten. När programmet körs på kommandoraden kan du använda metoden parse_args() på arg_parser för att få värdena för argumenten.

Här fångar vi argumentnamnutrymmet i variabeln args. Så du kan använda args.argument_name för att få värdena för argumenten.

Efter att ha fått värdena för argumenten skriver vi meddelandesträngen med skiftläge (med strängmetoden swapcase() till filen.

args = arg_parser.parse_args()

message = args.message
file = args.file

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

Här är vår 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())

Förstå användning av kommandoradsargument

För att förstå användningen av argumenten när du kör main.py kan du använda alternativet –help long som visas:

$ 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

Det finns inga valfria argument och både meddelande och fil är obligatoriska positionsargument. Alternativt kan du också använda det korta alternativet -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 sett är båda argumenten positionsargument som standard. Så om du inte skickar in ett eller flera av dessa argument kommer du att stöta på fel.

Här har vi skickat in ett positionsargument (Hej) för meddelandesträngen, men vi har inte angett något värde för filargumentet.

Och vi får ett felmeddelande om att filargumentet krävs.

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

När vi kör main.py med båda positionsargumenten ser vi att namnutrymmet args innehåller värdena för argumenten.

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

Om vi ​​nu undersöker innehållet i den nuvarande arbetskatalogen ser vi att skriptet skapar filen ’file1.txt’:

$ ls
file1.txt  main.py

Den ursprungliga meddelandesträngen är ’Hej’; efter att ha bytt skiftläge är meddelandesträngen i filen ’fil1.txt’ ’HEJ’.

$ cat file1.txt
hELLO

Hur man gör kommandoradsargument valfria

För att göra dessa kommandoradsargument valfria kan du prefixet argumentnamnet med –.

Låt oss ändra main.py för att göra både meddelandet och filargumenten valfria.

# main.py

from argparse import ArgumentParser

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

Eftersom kommandoradsargumenten båda är valfria kan vi ställa in standardvärden för dessa argument.

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

Vid det här laget innehåller filen main.py följande kod:

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

Om vi ​​kontrollerar användningen ser vi att både meddelande och fil är valfria argument. Det betyder att du nu kan köra main.py utan båda dessa 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

I argumentnamnutrymmet är både fil och meddelande Inga.

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

Vi ser att standardfilnamnet och meddelandet ’myfile.txt’ och ’Python3’ används. Filen ’myfile.txt’ finns nu i arbetskatalogen:

$ ls
file1.txt  main.py  myfile.txt

Och den innehåller strängen ’Python3’ med skiftläge för bokstäverna:

$ cat myfile.txt
pYTHON3

Du kan också använda både –meddelande och –fil-argumenten för att göra kommandot mer läsbart.

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

Vi ser ”file2.txt” i arbetskatalogen:

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

Och den innehåller strängen ’coDING’ som förväntat.

$ cat file2.txt
cODING

Slutsats

Här är en sammanfattning av vad vi har lärt oss i den här handledningen:

  • I likhet med programmeringsspråket C, i Python, kan du komma åt kommandoradsargumenten genom att gå igenom argumentvektorn sys.argv. sys.argv[0] är namnet på Python-skriptet. Så vi är intresserade av att analysera argumenten sys.argv[1:].
  • Men för att förbättra läsbarheten och för att kunna lägga till alternativ kan du använda för att getopt och argparse moduler.
  • Du kan använda modulen getopt för att analysera listan med kommandoradsargument från index 1 till slutet av listan. Du kan ange både korta och långa alternativ.
  • När ett alternativ tar ett argument kan du ange ett kolon (:) och = efter det korta alternativet respektive det långa alternativet.
  • Med Pythons argparse-modul kan du instansiera ett ArgumentParser-objekt och använda metoden add_argument() för att lägga till ett nödvändigt positionsargument. Använd — före argumentnamnet för att göra det valfritt.
  • För att hämta värdena för kommandoradsargumenten, anropar du metoden parse_args() på ArgumentParser-objektet.

Lär dig sedan hur du utför säker hash i Python.