optparse — Parser för kommandoradsalternativ

Källkod: Lib/optparse.py


Att välja ett bibliotek för argumentparsning

Standardbiblioteket innehåller tre bibliotek för parsning av argument:

  • getopt: en modul som nära speglar det procedurella C getopt API:et. Ingår i standardbiblioteket sedan före den första Python 1.0-utgåvan.

  • optparse: en deklarativ ersättning för getopt som ger likvärdig funktionalitet utan att kräva att varje applikation implementerar sin egen procedurella logik för att analysera alternativ. Ingår i standardbiblioteket sedan Python 2.3.

  • argparse: ett mer självständigt alternativ till optparse som ger mer funktionalitet som standard, på bekostnad av minskad flexibilitet för applikationer att kontrollera exakt hur argument bearbetas. Ingår i standardbiblioteket sedan Python 2.7 och Python 3.2.

I avsaknad av mer specifika designbegränsningar för argumentparsing är argparse det rekommenderade valet för implementering av kommandoradsapplikationer, eftersom det erbjuder den högsta nivån av basfunktionalitet med minst kod på applikationsnivå.

getopt behålls nästan helt och hållet av bakåtkompatibilitetsskäl. Den har dock också en nischad användning som ett verktyg för prototyper och testning av kommandoradsargumenthantering i getopt-baserade C-program.

optparse bör betraktas som ett alternativ till argparse i följande fall:

  • ett program använder redan optparse och vill inte riskera de subtila beteendeförändringar som kan uppstå när man migrerar till argparse

  • applikationen kräver ytterligare kontroll över hur alternativ och positionsparametrar interfolieras på kommandoraden (inklusive möjligheten att inaktivera interfolieringsfunktionen helt)

  • applikationen kräver ytterligare kontroll över den stegvisa tolkningen av kommandoradselement (även om argparse stöder detta, är det exakta sättet det fungerar i praktiken inte önskvärt för vissa användningsfall)

  • programmet kräver ytterligare kontroll över hanteringen av alternativ som accepterar parametervärden som kan börja med - (t.ex. delegerade alternativ som ska skickas till anropade underprocesser)

  • programmet kräver något annat beteende för bearbetning av kommandoradsparametrar som argparse inte stöder, men som kan implementeras i form av det gränssnitt på lägre nivå som erbjuds av optparse

Dessa överväganden innebär också att optparse sannolikt kommer att ge en bättre grund för biblioteksförfattare som skriver tredjeparts kommandoradsargumentbehandlingsbibliotek.

Ett konkret exempel är följande två konfigurationer för analys av argument på kommandoraden, där den första använder optparse och den andra argparse:

import optparse

if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-o', '--output')
    parser.add_option('-v', dest='verbose', action='store_true')
    opts, args = parser.parse_args()
    process(args, output=opts.output, verbose=opts.verbose)
import argparse

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-o', '--output')
    parser.add_argument('-v', dest='verbose', action='store_true')
    parser.add_argument('rest', nargs='*')
    args = parser.parse_args()
    process(args.rest, output=args.output, verbose=args.verbose)

Den mest uppenbara skillnaden är att i optparse-versionen bearbetas argumenten som inte är alternativ separat av programmet efter att alternativbearbetningen är klar. I argparse-versionen deklareras och bearbetas positionella argument på samma sätt som de namngivna alternativen.

Men argparse-versionen kommer också att hantera vissa parameterkombinationer på ett annat sätt än optparse-versionen skulle hantera dem. Till exempel (bland andra skillnader):

  • att tillhandahålla -o -v ger output="-v" och verbose=False när du använder optparse, men ett användningsfel med argparse (klagar på att inget värde har tillhandahållits för -o/--output, eftersom -v tolkas som att betyda verbosity-flaggan)

  • på samma sätt ger -o -- output="--" och args=() när du använder optparse, men ett användningsfel med argparse (klagar också på att inget värde har levererats för -o/--output, eftersom -- tolkas som att avsluta alternativbehandlingen och behandla alla återstående värden som positionella argument)

  • att leverera -o=foo ger output="=foo" när man använder optparse, men ger output="foo" med argparse (eftersom = är special cased som en alternativ separator för alternativparametervärden)

Huruvida dessa olika beteenden i argparse-versionen anses vara önskvärda eller ett problem beror på det specifika användningsfallet för kommandoradsapplikationen.

Se även

click är ett tredjepartsbibliotek för argumentbehandling (ursprungligen baserat på optparse), som gör det möjligt att utveckla kommandoradsapplikationer som en uppsättning dekorerade funktioner för implementering av kommandon.

Andra tredjepartsbibliotek, som typer eller msgspec-click, gör det möjligt att specificera kommandoradsgränssnitt på sätt som mer effektivt integrerar med statisk kontroll av Python-typannoteringar.

Introduktion

optparse är ett mer bekvämt, flexibelt och kraftfullt bibliotek för att analysera kommandoradsalternativ än den minimalistiska modulen getopt. optparse använder en mer deklarativ stil för kommandoradsanalys: du skapar en instans av OptionParser, fyller den med alternativ och analyserar kommandoraden. optparse låter användare ange alternativ i den konventionella GNU/POSIX-syntaxen och genererar dessutom användnings- och hjälpmeddelanden åt dig.

Här är ett exempel på användning av optparse i ett enkelt skript:

from optparse import OptionParser
...
parser = OptionParser()
parser.add_option("-f", "--file", dest="filnamn",
                  help="skriv rapport till FILE", metavar="FILE")
parser.add_option("-q", "--quiet",
                  action="store_false", dest="verbose", default=True,
                  help="skriv inte ut statusmeddelanden till stdout")

(alternativ, args) = parser.parse_args()

Med dessa få rader kod kan användare av ditt skript nu göra det ”vanliga” på kommandoraden, till exempel:

<yourscript> --file=outfile -q

När den analyserar kommandoraden ställer optparse in attribut för objektet options som returneras av parse_args() baserat på de kommandoradsvärden som användaren angett. När parse_args() återkommer efter att ha analyserat den här kommandoraden, kommer options.filename att vara "outfile" och options.verbose kommer att vara False. optparse stöder både långa och korta alternativ, tillåter att korta alternativ slås samman och tillåter att alternativ associeras med sina argument på en mängd olika sätt. Följande kommandorader är således alla likvärdiga med ovanstående exempel:

<yourscript> -f utfil --tyst
<yourscript> --tyst --fil utfil
<yourscript> -q -foutfile
<yourscript> -qfoutfile

Dessutom kan användare köra en av följande

<yourscript> -h
<yourscript> --hjälp

och optparse skriver ut en kort sammanfattning av skriptets alternativ:

Användning: <yourscript> [alternativ]

Alternativ:
  -h, --help visa detta hjälpmeddelande och avsluta
  -f FILE, --file=FILE skriva rapport till FILE
  -q, --quiet skriver inte ut statusmeddelanden till stdout

där värdet på yourscript bestäms vid körning (normalt från sys.argv[0]).

Bakgrund

optparse har uttryckligen utformats för att uppmuntra skapandet av program med enkla kommandoradsgränssnitt som följer de konventioner som etablerats av getopt()-familjen av funktioner som är tillgängliga för C-utvecklare. I detta syfte stöder programmet endast den vanligaste kommandoradssyntaxen och semantiken som används under Unix. Om du inte är bekant med dessa konventioner kan du läsa detta avsnitt för att bekanta dig med dem.

Terminologi

argument

en sträng som anges på kommandoraden och som skickas av skalet till execl() eller execv(). I Python är argument element i sys.argv[1:] (sys.argv[0] är namnet på det program som körs). Unix-skal använder också termen ”word”.

Det är ibland önskvärt att ersätta en annan argumentlista än sys.argv[1:], så du bör läsa ”argument” som ”ett element i sys.argv[1:], eller i någon annan lista som tillhandahålls som ett substitut för sys.argv[1:]”.

alternativ

ett argument som används för att ge extra information för att styra eller anpassa körningen av ett program. Det finns många olika syntaxer för alternativ; den traditionella Unix-syntaxen är ett bindestreck (”-”) följt av en enda bokstav, t.ex. -x eller -F. Den traditionella Unix-syntaxen tillåter också att flera alternativ slås samman till ett enda argument, t.ex. -x -F är likvärdigt med -xF. GNU-projektet introducerade -- följt av en serie bindestrecksseparerade ord, t.ex. --file eller --dry-run. Detta är de enda två syntaxerna för alternativ som tillhandahålls av optparse.

Några andra syntaxer för alternativ som världen har sett inkluderar:

  • ett bindestreck följt av några bokstäver, t.ex. -pf (detta är inte samma sak som flera alternativ som slås samman till ett enda argument)

  • ett bindestreck följt av ett helt ord, t.ex. -fil (detta är tekniskt sett likvärdigt med föregående syntax, men de förekommer vanligtvis inte i samma program)

  • ett plustecken följt av en eller flera bokstäver eller ett ord, t.ex. +f, +rgb

  • ett snedstreck följt av en bokstav, några bokstäver eller ett ord, t.ex. /f, /file

Dessa alternativsyntaxer stöds inte av optparse, och kommer aldrig att göra det. Detta är avsiktligt: de tre första är inte standard i någon miljö, och det sista är bara meningsfullt om du uteslutande riktar dig till Windows eller vissa äldre plattformar (t.ex. VMS, MS-DOS).

alternativ argument

ett argument som följer ett alternativ, är nära förknippat med det alternativet och konsumeras från argumentlistan när det alternativet är. Med optparse kan alternativargument antingen vara i ett separat argument från sitt alternativ:

-f foo
--fil foo

eller ingår i samma argument:

-ffoo
--fil=foo

Vanligtvis tar ett givet alternativ antingen ett argument eller så gör det inte det. Många människor vill ha en funktion för ”valfria alternativargument”, vilket innebär att vissa alternativ tar ett argument om de ser det, och inte om de inte gör det. Detta är något kontroversiellt, eftersom det gör parsing tvetydigt: om -a tar ett valfritt argument och -b är ett helt annat alternativ, hur tolkar vi -ab? På grund av denna tvetydighet har optparse inte stöd för denna funktion.

positionsargument

något som finns kvar i argumentlistan efter att alternativen har analyserats, dvs. efter att alternativen och deras argument har analyserats och tagits bort från argumentlistan.

önskat alternativ

ett alternativ som måste anges på kommandoraden; observera att frasen ”required option” är självmotsägande på engelska. optparse hindrar dig inte från att implementera nödvändiga alternativ, men ger dig inte mycket hjälp med det heller.

Tänk till exempel på denna hypotetiska kommandorad:

prog -v --rapport rapport.txt foo bar

-v och --report är båda alternativ. Om man antar att --report tar ett argument, är report.txt ett alternativargument. foo och bar är positionella argument.

Vad är alternativ till för?

Alternativ används för att ge extra information för att ställa in eller anpassa körningen av ett program. Om det inte framgick tydligt är optioner vanligtvis optionella. Ett program ska kunna köras alldeles utmärkt utan några som helst alternativ. (Välj ett slumpmässigt program från Unix- eller GNU-verktygsuppsättningarna. Kan det köras utan några alternativ alls och fortfarande vara vettigt? De viktigaste undantagen är find, tar och dd, som alla är muterade udda program som med rätta har kritiserats för sin icke-standardiserade syntax och förvirrande gränssnitt)

Många människor vill att deras program ska ha ”obligatoriska alternativ”. Tänk på det. Om det är obligatoriskt, då är det inte valfritt! Om det finns någon information som ditt program absolut behöver för att kunna köras framgångsrikt, så är det vad positionsargument är till för.

Som ett exempel på god design av kommandoradsgränssnitt kan man ta det enkla verktyget cp för kopiering av filer. Det är inte särskilt meningsfullt att försöka kopiera filer utan att ange en destination och minst en källa. Därför misslyckas cp om du kör det utan argument. Det har dock en flexibel och användbar syntax som inte kräver några alternativ alls:

cp SOURCE DEST
cp SOURCE ... DEST-DIR

Du kan komma ganska långt med bara det. De flesta cp-implementationer ger en massa alternativ för att justera exakt hur filerna kopieras: du kan bevara läge och modifieringstid, undvika att följa symlinks, fråga innan du kopierar befintliga filer, etc. Men inget av detta distraherar från kärnuppdraget för cp, vilket är att kopiera antingen en fil till en annan eller flera filer till en annan katalog.

Vad är positionsargument för?

Positionsargument är till för de delar av informationen som ditt program absolut, absolut måste ha för att kunna köras.

Ett bra användargränssnitt bör ha så få absoluta krav som möjligt. Om ditt program kräver 17 olika informationsbitar för att kunna köras framgångsrikt spelar det ingen större roll hur du får den informationen från användaren - de flesta kommer att ge upp och gå därifrån innan de lyckas köra programmet. Detta gäller oavsett om användargränssnittet är en kommandorad, en konfigurationsfil eller ett GUI: om du ställer så många krav på dina användare kommer de flesta av dem helt enkelt att ge upp.

Kort sagt, försök att minimera den mängd information som användarna absolut måste tillhandahålla - använd förnuftiga standardvärden när det är möjligt. Naturligtvis vill du också göra dina program rimligt flexibla. Det är vad alternativ är till för. Återigen, det spelar ingen roll om de är poster i en konfigurationsfil, widgets i dialogrutan ”Preferences” i ett GUI eller kommandoradsalternativ - ju fler alternativ du implementerar, desto mer flexibelt är ditt program och desto mer komplicerat blir dess implementering. För mycket flexibilitet har naturligtvis också nackdelar; för många alternativ kan göra användarna överväldigade och göra din kod mycket svårare att underhålla.

Handledning

Även om optparse är ganska flexibelt och kraftfullt är det också enkelt att använda i de flesta fall. I det här avsnittet beskrivs de kodmönster som är vanliga i alla optparse-baserade program.

Först måste du importera OptionParser-klassen; sedan, tidigt i huvudprogrammet, skapar du en OptionParser-instans:

from optparse import OptionParser
...
parser = OptionParser()

Sedan kan du börja definiera alternativ. Den grundläggande syntaxen är:

parser.add_option(opt_str, ...,
                  attr=värde, ...)

Varje alternativ har en eller flera alternativsträngar, t.ex. -f eller --file, och flera alternativattribut som talar om för optparse vad den kan förvänta sig och vad den ska göra när den stöter på alternativet på kommandoraden.

Vanligtvis har varje alternativ en kort alternativsträng och en lång alternativsträng, t.ex.:

parser.add_option("-f", "--file", ...)

Det står dig fritt att definiera så många korta alternativsträngar och så många långa alternativsträngar som du vill (inklusive noll), så länge det finns minst en alternativsträng totalt sett.

Alternativsträngarna som skickas till OptionParser.add_option() är i själva verket etiketter för det alternativ som definieras av det anropet. För korthetens skull kommer vi ofta att hänvisa till att möta ett alternativ på kommandoraden; i verkligheten möter optparse alternativsträngar och letar upp alternativ från dem.

När alla dina alternativ har definierats, instruerar du optparse att analysera ditt programs kommandorad:

(alternativ, args) = parser.parse_args()

(Om du vill kan du skicka en anpassad argumentlista till parse_args(), men det är sällan nödvändigt: som standard använder den sys.argv[1:])

parse_args() returnerar två värden:

  • options, ett objekt som innehåller värden för alla dina alternativ - t.ex. om --file tar ett enda strängargument, kommer options.file att vara det filnamn som användaren angav, eller None om användaren inte angav det alternativet

  • args, listan över positionella argument som återstår efter parsning av alternativ

I detta avsnitt behandlas endast de fyra viktigaste attributen för alternativ: action, type, dest (destination) och help. Av dessa är action den mest grundläggande.

Förståelse av alternativåtgärder

Åtgärder talar om för optparse vad den ska göra när den stöter på ett alternativ på kommandoraden. Det finns en fast uppsättning åtgärder hårdkodade i optparse; att lägga till nya åtgärder är ett avancerat ämne som behandlas i avsnittet Utökning av optparse. De flesta åtgärder säger åt optparse att lagra ett värde i någon variabel - till exempel att ta en sträng från kommandoraden och lagra den i ett attribut i options.

Om du inte anger någon alternativåtgärd är standardvärdet för optparse store.

Åtgärder i butiken

Det vanligaste alternativet är store, som säger till optparse att ta nästa argument (eller resten av det aktuella argumentet), se till att det är av rätt typ och lagra det på önskad plats.

Till exempel:

parser.add_option("-f", "--file",
                  action="lagra", type="sträng", dest="filnamn")

Låt oss nu skapa en falsk kommandorad och be optparse att tolka den:

args = ["-f", "foo.txt"]
(alternativ, args) = parser.parse_args(args)

När optparse ser alternativsträngen -f tar den nästa argument, foo.txt, och lagrar det i options.filename. Så efter detta anrop till parse_args() är options.filename "foo.txt".

Några andra alternativtyper som stöds av optparse är int och float. Här är ett alternativ som förväntar sig ett heltalsargument:

parser.add_option("-n", type="int", dest="num")

Observera att det här alternativet inte har någon lång alternativsträng, vilket är helt acceptabelt. Det finns inte heller någon explicit åtgärd, eftersom standardvärdet är store.

Låt oss analysera en annan falsk kommandorad. Den här gången ställer vi alternativargumentet rakt upp mot alternativet: eftersom -n42 (ett argument) är likvärdigt med -n 42 (två argument), blir koden

(alternativ, args) = parser.parse_args(["-n42"])
print(alternativ.nummer)

kommer att skriva ut 42.

Om du inte anger någon typ antar optparse string. Kombinerat med det faktum att standardåtgärden är store, betyder det att vårt första exempel kan vara mycket kortare:

parser.add_option("-f", "--file", dest="filnamn")

Om du inte anger någon destination räknar optparse ut en vettig standard från alternativsträngarna: om den första långa alternativsträngen är --foo-bar är standarddestinationen foo_bar. Om det inte finns några långa alternativsträngar tittar optparse på den första korta alternativsträngen: standarddestinationen för -f är f.

optparse innehåller också den inbyggda typen complex. Att lägga till typer behandlas i avsnitt Utökning av optparse.

Hantering av booleska (flagga) alternativ

Flaggalternativ - ställ in en variabel till sant eller falskt när ett visst alternativ visas - är ganska vanliga. optparse stöder dem med två separata åtgärder, store_true och store_false. Du kan till exempel ha en verbose-flagga som slås på med -v och av med -q:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose")

Här har vi två olika alternativ med samma destination, vilket är helt OK. (Det betyder bara att du måste vara lite försiktig när du ställer in standardvärden - se nedan)

När optparse stöter på -v på kommandoraden sätts options.verbose till True; när den stöter på -q sätts options.verbose till False.

Övriga handlingar

Några andra åtgärder som stöds av optparse är:

"store_const"

lagra ett konstant värde, förinställt via Option.const

"append"

lägg till argumentet för detta alternativ till en lista

"räkna"

öka en räknare med ett steg

"callback"

anropa en angiven funktion

Dessa behandlas i avsnitt Referensguide och avsnitt Option Callbacks.

Standardvärden

Alla exemplen ovan innebär att en variabel (destinationen) ställs in när vissa kommandoradsalternativ visas. Vad händer om dessa alternativ aldrig visas? Eftersom vi inte har angett några standardvärden sätts de alla till None. Detta är vanligtvis bra, men ibland vill du ha mer kontroll. optparse låter dig ange ett standardvärde för varje destination, som tilldelas innan kommandoraden analyseras.

Ta först exemplet med verbose/quiet. Om vi vill att optparse ska sätta verbose till True om inte -q ses, så kan vi göra så här:

parser.add_option("-v", action="store_true", dest="verbose", default=True)
parser.add_option("-q", action="store_false", dest="verbose")

Eftersom standardvärden gäller för destinationen snarare än för något särskilt alternativ, och dessa två alternativ råkar ha samma destination, är detta exakt likvärdigt:

parser.add_option("-v", action="store_true", dest="verbose")
parser.add_option("-q", action="store_false", dest="verbose", default=True)

Tänk på detta:

parser.add_option("-v", action="store_true", dest="verbose", default=False)
parser.add_option("-q", action="store_false", dest="verbose", default=True)

Återigen kommer standardvärdet för verbose att vara True: det sista standardvärdet som anges för en viss destination är det som räknas.

Ett tydligare sätt att ange standardvärden är metoden set_defaults() i OptionParser, som du kan anropa när som helst innan du anropar parse_args():

parser.set_defaults(verbose=True)
parser.add_option(...)
(alternativ, args) = parser.parse_args()

Som tidigare gäller att det är det sista värdet som anges för en given alternativdestination som räknas. För tydlighetens skull bör du försöka använda den ena eller den andra metoden för att ange standardvärden, inte båda.

Generera hjälp

optparse:s förmåga att automatiskt generera hjälp- och användningstext är användbar för att skapa användarvänliga kommandoradsgränssnitt. Allt du behöver göra är att ange ett help-värde för varje alternativ, och eventuellt ett kort användningsmeddelande för hela ditt program. Här är en OptionParser som är fylld med användarvänliga (dokumenterade) alternativ:

usage = "användning: %prog [alternativ] arg1 arg2"
parser = OptionParser(användning=användning)
parser.add_option("-v", "--verbose",
                  action="store_true", dest="verbose", default=True,
                  help="gör mycket ljud [default]")
parser.add_option("-q","--quiet",
                  action="store_false", dest="verbose",
                  help="var jättetyst (jag jagar wabbits)")
parser.add_option("-f","--filnamn",
                  metavar="FILE", help="skriv utdata till FILE")
parser.add_option("-m","--mode",
                  default="mellanläge",
                  help="interaktionsläge: nybörjare, mellanliggande, "
                       "eller expert [standard: %default]")

Om optparse stöter på antingen -h eller --help på kommandoraden, eller om du bara anropar parser.print_help(), skriver den ut följande till standardutmatningen:

Användning: <yourscript> [alternativ] arg1 arg2

Alternativ:
  -h, --help visa detta hjälpmeddelande och avsluta
  -v, --verbose gör mycket ljud [standard]
  -q, --quiet vara jättetyst (jag jagar wabbits)
  -f FILE, --filnamn=FILE
                        skriva utdata till FILE
  -m MODE, --mode=MODE interaktionsläge: nybörjare, medel eller
                        expert [standard: intermediär]

(Om hjälputmatningen utlöses av ett hjälpalternativ avslutas optparse efter att hjälptexten har skrivits ut)

Det är mycket som händer här för att hjälpa optparse att generera bästa möjliga hjälpmeddelande:

  • skriptet definierar sitt eget användningsmeddelande:

    usage = "användning: %prog [alternativ] arg1 arg2"
    

    optparse expanderar %prog i användningssträngen till namnet på det aktuella programmet, d.v.s. os.path.basename(sys.argv[0]). Den expanderade strängen skrivs sedan ut före den detaljerade alternativhjälpen.

    Om du inte anger någon användningssträng använder optparse en intetsägande men förnuftig standard: "Usage: %prog [options]", vilket är bra om ditt skript inte tar några positionella argument.

  • varje alternativ definierar en hjälpsträng och bryr sig inte om radbrytning — optparse tar hand om radbrytning och ser till att hjälputmatningen ser bra ut.

  • alternativ som tar ett värde anger detta faktum i sitt automatiskt genererade hjälpmeddelande, t.ex. för alternativet ”mode”:

    -m MODE, --mode=MODE
    

    Här kallas ”MODE” för meta-variabeln: den står för det argument som användaren förväntas ge till -m/--mode. Som standard konverterar optparse namnet på målvariabeln till versaler och använder det som metavariabel. Ibland är det inte vad du vill - till exempel, alternativet --filename sätter explicit metavar="FILE", vilket resulterar i denna automatiskt genererade alternativbeskrivning:

    -f FILE, --filnamn=FILE
    

    Detta är dock viktigt för mer än bara att spara utrymme: den manuellt skrivna hjälptexten använder metavariabeln FILE för att ge användaren en ledtråd om att det finns en koppling mellan den semi-formella syntaxen -f FILE och den informella semantiska beskrivningen ”skriv utdata till FILE”. Detta är ett enkelt men effektivt sätt att göra din hjälptext mycket tydligare och mer användbar för slutanvändarna.

  • alternativ som har ett standardvärde kan inkludera %default i hjälpsträngen—optparse kommer att ersätta det med str() av alternativets standardvärde. Om ett alternativ inte har något standardvärde (eller standardvärdet är None), expanderar %default till none.

Grupperingsalternativ

När man hanterar många alternativ är det praktiskt att gruppera dessa alternativ för bättre hjälputmatning. En OptionParser kan innehålla flera alternativgrupper, som var och en kan innehålla flera alternativ.

En optionsgrupp erhålls med hjälp av klassen OptionGroup:

class optparse.OptionGroup(parser, title, description=None)

där

  • parser är OptionParser-instansen som gruppen kommer att infogas i för att

  • title är gruppens titel

  • description, valfritt, är en lång beskrivning av gruppen

OptionGroup ärver från OptionContainer (liksom OptionParser) och därför kan metoden add_option() användas för att lägga till ett alternativ i gruppen.

När alla alternativ har deklarerats, med hjälp av OptionParser-metoden add_option_group(), läggs gruppen till i den tidigare definierade parsern.

Om vi fortsätter med den parser som definierades i föregående avsnitt är det enkelt att lägga till en OptionGroup till en parser:

group = OptionGroup(parser, "Farliga alternativ",
                    "Varning: använd dessa alternativ på egen risk.  "
                    "Det tros att vissa av dem biter.")
group.add_option("-g", action="store_true", help="Gruppalternativ.")
parser.add_option_group(grupp)

Detta skulle resultera i följande hjälputskrift:

Användning: <yourscript> [alternativ] arg1 arg2

Alternativ:
  -h, --help visa detta hjälpmeddelande och avsluta
  -v, --verbose gör mycket ljud [standard]
  -q, --quiet vara jättetyst (jag jagar wabbits)
  -f FILE, --filnamn=FILE
                        skriva utdata till FILE
  -m MODE, --mode=MODE interaktionsläge: nybörjare, medel eller
                        expert [standard: intermediär]

  Farliga alternativ:
    Varning: Använd dessa alternativ på egen risk.  Det tros att vissa av dem
    av dem biter.

    -g Gruppalternativ.

Ett lite mer komplett exempel skulle kunna innebära att man använder mer än en grupp: som en fortsättning på det tidigare exemplet:

group = OptionGroup(parser, "Farliga alternativ",
                    "Varning: använd dessa alternativ på egen risk.  "
                    "Det tros att vissa av dem biter.")
group.add_option("-g", action="store_true", help="Gruppalternativ.")
parser.add_option_group(grupp)

group = OptionGroup(parser, "Alternativ för felsökning")
group.add_option("-d", "--debug", action="store_true",
                 help="Skriv ut felsökningsinformation")
group.add_option("-s", "--sql", action="store_true",
                 help="Skriv ut alla SQL-satser som körts")
group.add_option("-e", action="store_true", help="Skriv ut alla åtgärder som utförts")
parser.add_option_group(grupp)

som resulterar i följande utdata:

Användning: <yourscript> [alternativ] arg1 arg2

Alternativ:
  -h, --help visa detta hjälpmeddelande och avsluta
  -v, --verbose gör mycket ljud [standard]
  -q, --quiet vara jättetyst (jag jagar wabbits)
  -f FILE, --filnamn=FILE
                        skriva utdata till FILE
  -m MODE, --mode=MODE interaktionsläge: nybörjare, medel eller expert
                        [standard: intermediär]

  Farliga alternativ:
    Varning: Använd dessa alternativ på egen risk.  Det tros att vissa av dem
    av dem biter.

    -g Gruppalternativ.

  Alternativ för debuggning:
    -d, --debug Skriv ut felsökningsinformation
    -s, --sql Skriv ut alla SQL-satser som körts
    -e Skriv ut alla utförda åtgärder

En annan intressant metod, särskilt när man arbetar programmatiskt med optionsgrupper, är

OptionParser.get_option_group(opt_str)

Returnerar den OptionGroup till vilken den korta eller långa optionssträngen opt_str (t.ex. '-o' eller '--option') hör. Om det inte finns någon sådan OptionGroup, returneras None.

Skriva ut en versionssträng

I likhet med den korta användningssträngen kan optparse också skriva ut en versionssträng för ditt program. Du måste ange strängen som argumentet version till OptionParser:

parser = OptionParser(usage="%prog [-f] [-q]", version="%prog 1.0")

%prog är expanderat precis som det är i usage. Bortsett från det kan version innehålla vad du vill. När du anger det, lägger optparse automatiskt till ett --version-alternativ till din parser. Om den stöter på detta alternativ på kommandoraden, expanderar den din version-sträng (genom att ersätta %prog), skriver ut den till stdout och avslutar.

Om ditt skript till exempel heter /usr/bin/foo:

$ /usr/bin/foo --version
foo 1.0

Följande två metoder kan användas för att skriva ut och hämta version-strängen:

OptionParser.print_version(file=None)

Skriver ut versionsmeddelandet för det aktuella programmet (self.version) till fil (standard stdout). Precis som med print_usage() ersätts alla förekomster av %prog i self.version med namnet på det aktuella programmet. Gör ingenting om self.version är tom eller odefinierad.

OptionParser.get_version()

Samma sak som print_version() men returnerar versionssträngen i stället för att skriva ut den.

Hur optparse hanterar fel

Det finns två stora klasser av fel som optparse måste ta hand om: programmeringsfel och användarfel. Programmeringsfel är vanligtvis felaktiga anrop till OptionParser.add_option(), t.ex. ogiltiga alternativsträngar, okända alternativattribut, saknade alternativattribut, etc. Dessa hanteras på vanligt sätt: skapa ett undantag (antingen optparse.OptionError eller TypeError) och låt programmet krascha.

Hantering av användarfel är mycket viktigare, eftersom de garanterat kommer att inträffa oavsett hur stabil din kod är. optparse kan automatiskt upptäcka vissa användarfel, t.ex. dåliga alternativargument (skicka -n 4x där -n tar ett heltalsargument), saknade argument (-n i slutet av kommandoraden, där -n tar ett argument av valfri typ). Du kan också anropa OptionParser.error() för att signalera ett programdefinierat feltillstånd:

(alternativ, args) = parser.parse_args()
...
om alternativ.a och alternativ.b:
    parser.error("alternativen -a och -b är ömsesidigt uteslutande")

I båda fallen hanterar optparse felet på samma sätt: det skriver ut programmets användningsmeddelande och ett felmeddelande till standardfelet och avslutas med felstatus 2.

Tänk på det första exemplet ovan, där användaren ger 4x till ett alternativ som tar ett heltal:

$ /usr/bin/foo -n 4x
Användning: foo [alternativ]

foo: fel: alternativ -n: ogiltigt heltalsvärde: '4x'

Eller där användaren inte skickar något värde alls:

$ /usr/bin/foo -n
Användning: foo [alternativ]

foo: fel: alternativet -n kräver ett argument

optparse -genererade felmeddelanden är noga med att alltid nämna det alternativ som är inblandat i felet; se till att göra detsamma när du anropar OptionParser.error() från din programkod.

Om optparse standardfelhanteringsbeteende inte passar dina behov, måste du underklassa OptionParser och åsidosätta dess exit() och/eller error() metoder.

Att sätta ihop allt

Så här ser optparse -baserade skript vanligtvis ut:

from optparse import OptionParser
...
def main():
    användning = "användning: %prog [alternativ] arg"
    parser = OptionParser(användning)
    parser.add_option("-f", "--file", dest="filnamn",
                      help="läs data från FILNAMN")
    parser.add_option("-v", "--verbose",
                      action="store_true", dest="verbose")
    parser.add_option("-q", "--quiet",
                      action="store_false", dest="verbose")
    ...
    (alternativ, args) = parser.parse_args()
    om len(args) != 1:
        parser.error("felaktigt antal argument")
    if options.verbose:
        print("läser %s..." % options.filnamn)
    ...

if __name__ == "__main__":
    main()

Referensguide

Skapa parsern

Det första steget i användningen av optparse är att skapa en OptionParser-instans.

class optparse.OptionParser(...)

OptionParser-konstruktören har inga obligatoriska argument, men ett antal valfria nyckelordsargument. Du bör alltid skicka dem som nyckelordsargument, dvs. inte förlita dig på den ordning i vilken argumenten deklareras.

usage (standard: "%prog [options]")

Den användningsöversikt som ska skrivas ut när programmet körs felaktigt eller med ett hjälpalternativ. När optparse skriver ut användningssträngen expanderar den %prog till os.path.basename(sys.argv[0]) (eller till prog om du angav det nyckelordet som argument). För att undertrycka ett användningsmeddelande, skicka det speciella värdet optparse.SUPPRESS_USAGE.

option_list (standard: [])

En lista med Option-objekt att fylla parsern med. Alternativen i option_list läggs till efter eventuella alternativ i standard_option_list (ett klassattribut som kan ställas in av OptionParser-subklasser), men före eventuella versions- eller hjälpalternativ. Utgår; använd add_option() efter att parsern skapats istället.

option_class (standard: optparse.Option)

Klass som ska användas när alternativ läggs till i parsern i add_option().

version (standard: None)

En versionssträng som skrivs ut när användaren anger ett versionsalternativ. Om du anger ett sant värde för version, lägger optparse automatiskt till ett versionsalternativ med den enkla optionssträngen --version. Understrängen %prog expanderas på samma sätt som för usage.

conflict_handler (standard: "error")

Anger vad som ska göras när alternativ med motstridiga alternativsträngar läggs till i parsern; se avsnitt Konflikter mellan olika alternativ.

description (standard: None)

Ett stycke text som ger en kort översikt över ditt program. optparse omformaterar detta stycke så att det passar den aktuella terminalbredden och skriver ut det när användaren ber om hjälp (efter usage, men före listan med alternativ).

formatter (standard: en ny IndentedHelpFormatter)

En instans av optparse.HelpFormatter som kommer att användas för att skriva ut hjälptext. optparse tillhandahåller två konkreta klasser för detta ändamål: IndentedHelpFormatter och TitledHelpFormatter.

add_help_option (standard: True)

Om true, kommer optparse att lägga till ett hjälpalternativ (med alternativsträngarna -h och --help) till parsern.

prog

Den sträng som ska användas när %prog expanderas i usage och version istället för os.path.basename(sys.argv[0]).

epilog (standard: None)

Ett stycke hjälptext som ska skrivas ut efter alternativet help.

Fylla på parsern

Det finns flera sätt att fylla på parsern med alternativ. Det föredragna sättet är att använda OptionParser.add_option(), som visas i avsnitt Handledning. add_option() kan anropas på ett av två sätt:

  • skicka en Option-instans till den (som returneras av make_option())

  • skicka valfri kombination av positions- och nyckelordsargument som är acceptabla för make_option() (dvs. för Option-konstruktören), så skapar den Option-instansen åt dig

Det andra alternativet är att skicka en lista med förkonstruerade Option-instanser till OptionParser-konstruktören, som i:

option_list = [
    make_option("-f", "--filnamn",
                action="lagra", type="sträng", dest="filnamn"),
    make_option("-q", "--quiet",
                action="store_false", dest="verbose"),
    ]
parser = OptionParser(option_list=option_list)

(make_option() är en fabriksfunktion för att skapa Option-instanser; för närvarande är det ett alias för Option-konstruktören. En framtida version av optparse kan dela upp Option i flera klasser, och make_option() kommer att välja rätt klass att instansiera. Instansiera inte Option direkt)

Definiera alternativ

Varje Option-instans representerar en uppsättning synonyma kommandoradsalternativsträngar, t.ex. -f och --file. Du kan ange ett valfritt antal korta eller långa alternativsträngar, men du måste ange minst en övergripande alternativsträng.

Det kanoniska sättet att skapa en instans av Option är med metoden add_option() i OptionParser.

OptionParser.add_option(option)
OptionParser.add_option(*opt_str, attr=value, ...)

För att definiera ett alternativ med endast en kort alternativsträng:

parser.add_option("-f", attr=värde, ...)

Och för att definiera ett alternativ med endast en lång alternativsträng:

parser.add_option("--foo", attr=värde, ...)

Nyckelordsargumenten definierar attribut för det nya Option-objektet. Det viktigaste attributet är action, och det avgör till stor del vilka andra attribut som är relevanta eller obligatoriska. Om du skickar irrelevanta optionsattribut eller inte skickar nödvändiga sådana, ger optparse upphov till ett OptionError undantag som förklarar ditt misstag.

Ett alternativs action avgör vad optparse gör när den stöter på detta alternativ på kommandoraden. De standardåtgärder för alternativ som är hårdkodade i optparse är:

"butik"

lagra argumentet för detta alternativ (standard)

"store_const"

lagra ett konstant värde, förinställt via Option.const

"store_true"

lagra True

"store_false"

lagra False

"append"

lägg till argumentet för detta alternativ till en lista

"append_const"

lägger till ett konstant värde till en lista, förinställt via Option.const

"räkna"

öka en räknare med ett steg

"callback"

anropa en angiven funktion

"hjälp"

skriva ut ett användningsmeddelande som innehåller alla alternativ och dokumentationen för dem

(Om du inte anger någon åtgärd är standardvärdet "store". För denna åtgärd kan du också ange alternativattributen type och dest; se Standardalternativ för åtgärder.)

Som du kan se handlar de flesta åtgärder om att lagra eller uppdatera ett värde någonstans. optparse skapar alltid ett speciellt objekt för detta, konventionellt kallat options, som är en instans av optparse.Values.

class optparse.Values

Ett objekt som innehåller namn och värden för analyserade argument som attribut. Skapas normalt genom att anropa OptionParser.parse_args(), och kan åsidosättas av en anpassad underklass som skickas till values-argumentet i OptionParser.parse_args() (enligt beskrivningen i Tolkning av argument).

Alternativargument (och diverse andra värden) lagras som attribut för detta objekt, enligt alternativattributet dest (destination).

Till exempel när du ringer

parser.parse_args()

en av de första sakerna som optparse gör är att skapa objektet options:

alternativ = Värden()

Om ett av alternativen i denna parser definieras med

parser.add_option("-f", "--file", action="store", type="string", dest="filename")

och kommandoraden som analyseras innehåller något av följande:

-ffoo
-f foo
--file=foo
--fil foo

då kommer optparse, när den ser detta alternativ, att göra motsvarande

alternativ.filnamn = "foo"

Alternativattributen type och dest är nästan lika viktiga som action, men action är det enda som är meningsfullt för alla alternativ.

Attribut för alternativ

class optparse.Option

Ett enda kommandoradsargument, med olika attribut som skickas med nyckelord till konstruktören. Skapas normalt med OptionParser.add_option() snarare än direkt, och kan åsidosättas av en anpassad klass via argumentet option_class till OptionParser.

Följande optionsattribut kan skickas som nyckelordsargument till OptionParser.add_option(). Om du skickar ett alternativattribut som inte är relevant för ett visst alternativ, eller misslyckas med att skicka ett obligatoriskt alternativattribut, ger optparse upphov till OptionError.

Option.action

(standard: "store")

Bestämmer optparse beteende när detta alternativ visas på kommandoraden; de tillgängliga alternativen finns dokumenterade här.

Option.type

(standard: "sträng")

Den argumenttyp som förväntas av detta alternativ (t.ex. "string" eller "int"); de tillgängliga alternativtyperna finns dokumenterade här.

Option.dest

(standard: härledd från optionssträngar)

Om optionens åtgärd innebär att ett värde skrivs eller ändras någonstans, talar detta om för optparse var det ska skrivas: dest namnger ett attribut i objektet options som optparse bygger upp när den analyserar kommandoraden.

Option.default

Det värde som ska användas för detta alternativs destination om alternativet inte visas på kommandoraden. Se även OptionParser.set_defaults().

Option.nargs

(standard: 1)

Hur många argument av typen type som ska användas när detta alternativ visas. Om > 1, kommer optparse att lagra en tupel av värden till dest.

Option.const

För åtgärder som lagrar ett konstant värde, det konstanta värde som ska lagras.

Option.choices

För alternativ av typen "choice", listan med strängar som användaren kan välja mellan.

Option.callback

För alternativ med åtgärden "callback", den anropbara funktionen som ska anropas när detta alternativ visas. Se avsnitt Option Callbacks för detaljer om de argument som skickas till anropsbarnet.

Option.callback_args
Option.callback_kwargs

Ytterligare positions- och nyckelordsargument att skicka till callback efter de fyra standardargumenten för återuppringning.

Option.help

Hjälptext som ska skrivas ut för detta alternativ när alla tillgängliga alternativ listas efter att användaren har angett ett help-alternativ (t.ex. --help). Om ingen hjälptext anges kommer alternativet att listas utan hjälptext. Om du vill dölja det här alternativet använder du specialvärdet optparse.SUPPRESS_HELP.

Option.metavar

(standard: härledd från optionssträngar)

Ersättare för det eller de alternativargument som ska användas vid utskrift av hjälptext. Se avsnitt Handledning för ett exempel.

Standardalternativ för åtgärder

De olika alternativåtgärderna har alla lite olika krav och effekter. De flesta åtgärder har flera relevanta alternativattribut som du kan ange för att styra optparse:s beteende; några få har obligatoriska attribut som du måste ange för alla alternativ som använder den åtgärden.

  • "store" [relevant: type, dest, nargs, choices]

    Alternativet måste följas av ett argument, som konverteras till ett värde enligt type och lagras i dest. Om nargs > 1, kommer flera argument att hämtas från kommandoraden; alla kommer att konverteras enligt type och lagras i dest som en tupel. Se avsnittet Typer av standardtillval.

    Om choices anges (en lista eller tupel av strängar), är typen standardmässigt "choice".

    Om type inte anges är standardvärdet "string".

    Om dest inte anges, härleder optparse en destination från den första långa alternativsträngen (t.ex. --foo-bar implicerar foo_bar). Om det inte finns några långa alternativsträngar, härleder optparse en destination från den första korta alternativsträngen (t.ex. -f implicerar f).

    Exempel:

    parser.add_option("-f")
    parser.add_option("-p", type="float", nargs=3, dest="point")
    

    När den analyserar kommandoraden

    -f foo.txt -p 1 -3.5 4 -fbar.txt
    

    optparse kommer att ställa in

    options.f = "foo.txt"
    options.point = (1.0, -3.5, 4.0)
    options.f = "bar.txt"
    
  • "store_const" [required: const; relevant: dest]

    Värdet const lagras i dest.

    Exempel:

    parser.add_option("-q", "--quiet",
                      action="store_const", const=0, dest="verbose")
    parser.add_option("-v", "--verbose",
                      action="store_const", const=1, dest="verbose")
    parser.add_option("--noisy",
                      action="store_const", const=2, dest="verbose")
    

    Om --noisy ses, kommer optparse att sätta

    options.verbose = 2
    
  • "store_true" [relevant: dest]

    Ett specialfall av "store_const" som lagrar True till dest.

  • "store_false" [relevant: dest]

    Som "store_true", men lagrar False.

    Exempel:

    parser.add_option("--clobber", action="store_true", dest="clobber")
    parser.add_option("--no-clobber", action="store_false", dest="clobber")
    
  • "append" [relevant: type, dest, nargs, choices]

    Alternativet måste följas av ett argument som läggs till i listan i dest. Om inget standardvärde anges för dest skapas automatiskt en tom lista när optparse för första gången möter detta alternativ på kommandoraden. Om nargs > 1, används flera argument och en tupel med längden nargs läggs till dest.

    Standardvärdena för type och dest är desamma som för åtgärden "store".

    Exempel:

    parser.add_option("-t", "--tracks", action="append", type="int")
    

    Om -t3 visas på kommandoraden gör optparse motsvarande:

    options.tracks = []
    options.tracks.append(int("3"))
    

    Om man lite senare ser --tracks=4 så gör den det:

    options.tracks.append(int("4"))
    

    Åtgärden append anropar metoden append på det aktuella värdet för alternativet. Detta innebär att alla standardvärden som anges måste ha en append-metod. Det innebär också att om standardvärdet inte är tomt kommer standardelementen att finnas i det analyserade värdet för alternativet, med eventuella värden från kommandoraden tillagda efter dessa standardvärden:

    >>> parser.add_option("--files", action="append", default=['~/.mypkg/defaults'])
    >>> opts, args = parser.parse_args(['--files', 'overrides.mypkg'])
    >>> opts.files
    ['~/.mypkg/defaults', 'overrides.mypkg']
    
  • "append_const" [required: const; relevant: dest]

    Som "store_const", men värdet const läggs till dest; som med "append", är dest standardvärdet None, och en tom lista skapas automatiskt första gången alternativet påträffas.

  • "count" [relevant: dest]

    Ökar det heltal som lagras i dest. Om inget standardvärde anges, sätts dest till noll innan det ökas första gången.

    Exempel:

    parser.add_option("-v", action="count", dest="verbosity")
    

    Första gången -v syns på kommandoraden gör optparse motsvarande:

    options.verbosity = 0
    options.verbosity += 1
    

    Varje efterföljande förekomst av -v resulterar i

    options.verbosity += 1
    
  • "callback" [required: callback; relevant: type, nargs, callback_args, callback_kwargs]

    Anropa den funktion som anges av callback, som anropas som

    func(option, opt_str, värde, parser, *args, **kwargs)
    

    Se avsnitt Option Callbacks för mer information.

  • "hjälp"

    Skriver ut ett komplett hjälpmeddelande för alla alternativ i den aktuella alternativparsern. Hjälpmeddelandet konstrueras utifrån strängen usage som skickas till OptionParser-konstruktören och strängen help som skickas till varje alternativ.

    Om ingen help-sträng anges för ett alternativ kommer det ändå att anges i hjälpmeddelandet. Om du vill utelämna ett alternativ helt använder du specialvärdet optparse.SUPPRESS_HELP.

    optparse lägger automatiskt till ett help-alternativ till alla OptionParsers, så du behöver normalt inte skapa ett.

    Exempel:

    from optparse import OptionParser, SUPPRESS_HELP
    
    # vanligtvis läggs ett hjälpalternativ till automatiskt, men det kan
    # undertryckas med hjälp av argumentet add_help_option
    parser = OptionParser(add_help_option=False)
    
    parser.add_option("-h", "--help", action="help")
    parser.add_option("-v", action="store_true", dest="verbose",
                      help="Var måttligt utförlig")
    parser.add_option("--file", dest="filnamn",
                      help="Inmatningsfil att läsa data från")
    parser.add_option("--secret", help=SUPPRESS_HELP)
    

    Om optparse ser antingen -h eller --help på kommandoraden kommer den att skriva ut något i stil med följande hjälpmeddelande till stdout (förutsatt att sys.argv[0] är "foo.py"):

    Användning: foo.py [alternativ]
    
    Alternativ:
      -h, --help Visa detta hjälpmeddelande och avsluta
      -v Var måttligt utförlig
      --file=FILENAME Inmatningsfil att läsa data från
    

    Efter att ha skrivit ut hjälpmeddelandet avslutar optparse din process med sys.exit(0).

  • "version"

    Skriver ut versionsnumret som angetts till OptionParser på stdout och avslutar. Versionsnumret formateras faktiskt och skrivs ut med metoden print_version() i OptionParser. I allmänhet endast relevant om argumentet version anges i OptionParser-konstruktören. Precis som med help-alternativen kommer du sällan att skapa version-alternativ, eftersom optparse automatiskt lägger till dem när de behövs.

Typer av standardtillval

optparse har fem inbyggda alternativtyper: "string", "int", "choice", "float" och "complex". Om du behöver lägga till nya alternativtyper, se avsnitt Utökning av optparse.

Argument till strängalternativ kontrolleras eller konverteras inte på något sätt: texten på kommandoraden lagras i destinationen (eller skickas till återuppringningen) som den är.

Heltalsargument (typ "int") tolkas på följande sätt:

  • om talet börjar med 0x, tolkas det som ett hexadecimalt tal

  • om talet börjar med 0, tolkas det som ett oktalt tal

  • om talet börjar med 0b, tolkas det som ett binärt tal

  • annars tolkas talet som ett decimaltal

Omvandlingen görs genom att anropa int() med lämplig bas (2, 8, 10 eller 16). Om detta misslyckas, gör även optparse det, men med ett mer användbart felmeddelande.

alternativargumenten "float" och "complex" konverteras direkt med float() och complex(), med liknande felhantering.

"choice"-alternativ är en subtyp av "string"-alternativ. Alternativattributet choices (en sekvens av strängar) definierar uppsättningen av tillåtna alternativargument. optparse.check_choice() jämför användartillhandahållna alternativargument mot denna huvudlista och ger upphov till OptionValueError om en ogiltig sträng anges.

Tolkning av argument

Hela poängen med att skapa och fylla i en OptionParser är att anropa dess parse_args()-metod.

OptionParser.parse_args(args=None, values=None)

Analyserar kommandoradsalternativen som finns i args.

Ingångsparametrarna är

args

listan med argument som ska bearbetas (standard: sys.argv[1:])

värden

ett Values-objekt att lagra alternativargument i (standard: en ny instans av Values) – om du anger ett befintligt objekt kommer alternativinställningarna inte att initialiseras på det

och returvärdet är ett par (options, args) där

alternativ

samma objekt som skickades in som values, eller instansen optparse.Values som skapades av optparse

args

de kvarvarande positionsargumenten efter att alla alternativ har behandlats

Den vanligaste användningen är att inte ange något nyckelordsargument. Om du anger values kommer det att modifieras med upprepade setattr()-anrop (ungefär ett för varje alternativargument som lagras i en alternativdestination) och returneras av parse_args().

Om parse_args() stöter på några fel i argumentlistan anropas OptionParsers metod error() med ett lämpligt felmeddelande för slutanvändaren. Detta avslutar slutligen din process med en utgångsstatus på 2 (den traditionella Unix-utgångsstatusen för kommandoradsfel).

Förfrågan och manipulering av din optionsparser

Standardbeteendet för optionsparsern kan anpassas något, och du kan också rota runt i din optionsparser och se vad som finns där. OptionParser tillhandahåller flera metoder för att hjälpa dig:

OptionParser.disable_interspersed_args()

Ställ in parsning så att den stoppas vid det första icke-alternativet. Till exempel, om -a och -b båda är enkla alternativ som inte tar några argument, accepterar optparse normalt denna syntax:

prog -a arg1 -b arg2

och behandlar det som likvärdigt med

prog -a -b arg1 arg2

För att inaktivera den här funktionen, anropa disable_interspersed_args(). Detta återställer traditionell Unix-syntax, där parsning av alternativ slutar med det första argumentet som inte är ett alternativ.

Använd detta om du har en kommandoprocessor som kör ett annat kommando som har egna alternativ och du vill se till att dessa alternativ inte blandas ihop. Varje kommando kan t.ex. ha olika uppsättningar alternativ.

OptionParser.enable_interspersed_args()

Ställ in parsning så att den inte stoppas vid det första icke-alternativet, vilket gör det möjligt att varva omkopplare med kommandoparametrar. Detta är standardbeteendet.

OptionParser.get_option(opt_str)

Returnerar Option-instansen med optionssträngen opt_str, eller None om inga optioner har den optionssträngen.

OptionParser.has_option(opt_str)

Returnerar True om OptionParser har ett alternativ med alternativsträngen opt_str (t.ex. -q eller --verbose).

OptionParser.remove_option(opt_str)

Om OptionParser har ett alternativ som motsvarar opt_str, tas det alternativet bort. Om det alternativet innehöll några andra alternativsträngar, blir alla dessa alternativsträngar ogiltiga. Om opt_str inte förekommer i något alternativ som tillhör denna OptionParser, utlöses ValueError.

Konflikter mellan olika alternativ

Om du inte är försiktig är det lätt att definiera alternativ med motstridiga alternativsträngar:

parser.add_option("-n", "--dry-run", ...)
...
parser.add_option("-n", "--noisy", ...)

(Detta gäller i synnerhet om du har definierat din egen OptionParser-underklass med några standardalternativ)

Varje gång du lägger till ett alternativ kontrollerar optparse om det finns konflikter med befintliga alternativ. Om den hittar några, anropar den den aktuella konflikthanteringsmekanismen. Du kan ställa in konflikthanteringsmekanismen antingen i konstruktören:

parser = OptionParser(..., conflict_handler=handler)

eller med ett separat anrop:

parser.set_conflict_handler(handler)

De tillgängliga konflikthanterarna är:

"error" (standard)

anta att optionskonflikter är ett programmeringsfel och skapa OptionConflictError

"resolve"

lösa optionskonflikter på ett intelligent sätt (se nedan)

Som ett exempel kan vi definiera en OptionParser som löser konflikter på ett intelligent sätt och lägga till konfliktfyllda alternativ i den:

parser = OptionParser(conflict_handler="resolve")
parser.add_option("-n","--dry-run", ..., help="gör ingen skada")
parser.add_option("-n", "--noisy", ..., help="var högljudd")

Vid denna punkt upptäcker optparse att ett tidigare tillagt alternativ redan använder alternativsträngen -n. Eftersom conflict_handler är "resolve", löser den situationen genom att ta bort -n från det tidigare alternativets lista över alternativsträngar. Nu är --dry-run det enda sättet för användaren att aktivera det alternativet. Om användaren ber om hjälp kommer detta att framgå av hjälpmeddelandet:

Alternativ:
  --dry-run gör ingen skada
  ...
  -n, --noisy vara högljudd

Det är möjligt att ta bort alternativsträngarna för ett tidigare tillagt alternativ tills det inte finns några kvar, och användaren inte har något sätt att använda alternativet från kommandoraden. I så fall tar optparse bort alternativet helt och hållet, så att det inte visas i hjälptexten eller någon annanstans. Fortsätter med vår befintliga OptionParser:

parser.add_option("--dry-run", ..., help="nytt alternativ för torrkörning")

Vid denna tidpunkt är det ursprungliga alternativet -n/--dry-run inte längre tillgängligt, så optparse tar bort det och lämnar denna hjälptext:

Alternativ:
  ...
  -n, --noisy vara högljudd
  --dry-run nytt alternativ för torrkörning

Rensa upp

OptionParser-instanser har flera cykliska referenser. Detta bör inte vara något problem för Pythons skräpsamlare, men du kanske vill bryta de cykliska referenserna explicit genom att anropa destroy() på din OptionParser när du är klar med den. Detta är särskilt användbart i långkörande applikationer där stora objektgrafer kan nås från din OptionParser.

Andra metoder

OptionParser stöder flera andra publika metoder:

OptionParser.set_usage(usage)

Ställ in användningssträngen enligt de regler som beskrivs ovan för nyckelordsargumentet usage i konstruktören. Om du skickar None anges standardanvändningssträngen; använd optparse.SUPPRESS_USAGE för att undertrycka ett användningsmeddelande.

OptionParser.print_usage(file=None)

Skriv ut användningsmeddelandet för det aktuella programmet (self.usage) till fil (standard stdout). Alla förekomster av strängen %prog i self.usage ersätts med namnet på det aktuella programmet. Gör ingenting om self.usage är tom eller inte definierad.

OptionParser.get_usage()

Samma sak som print_usage() men returnerar användningssträngen i stället för att skriva ut den.

OptionParser.set_defaults(dest=value, ...)

Ange standardvärden för flera alternativdestinationer på en gång. Att använda set_defaults() är det bästa sättet att ange standardvärden för alternativ, eftersom flera alternativ kan dela samma destination. Om t.ex. flera ”mode”-alternativ anger samma destination kan vilket som helst av dem ange standardvärdet, och det sista alternativet vinner:

parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced",
                  default="nybörjare")    # åsidosätts nedan
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice",
                  default="avancerad")  # åsidosätter ovanstående inställning

För att undvika denna förvirring, använd set_defaults():

parser.set_defaults(mode="advanced")
parser.add_option("--advanced", action="store_const",
                  dest="mode", const="advanced")
parser.add_option("--novice", action="store_const",
                  dest="mode", const="novice")

Option Callbacks

När optparse:s inbyggda åtgärder och typer inte räcker till för dina behov har du två val: utöka optparse eller definiera ett återuppringningsalternativ. Att utöka optparse är mer generellt, men överdrivet i många enkla fall. Ofta är en enkel återuppringning allt du behöver.

Det finns två steg för att definiera ett callback-alternativ:

  • definiera själva alternativet med hjälp av åtgärden "callback"

  • skriv återuppringningen; detta är en funktion (eller metod) som tar minst fyra argument, enligt beskrivningen nedan

Definiera ett återuppringningsalternativ

Som alltid är det enklaste sättet att definiera ett callback-alternativ att använda metoden OptionParser.add_option(). Förutom action är det enda alternativattributet du måste ange callback, funktionen som ska anropas:

parser.add_option("-c", action="callback", callback=my_callback)

callback är en funktion (eller annat anropbart objekt), så du måste redan ha definierat my_callback() när du skapar detta callback-alternativ. I det här enkla fallet vet optparse inte ens om -c tar några argument, vilket vanligtvis betyder att alternativet inte tar några argument–den blotta närvaron av -c på kommandoraden är allt den behöver veta. Under vissa omständigheter kan du dock vilja att din återuppringning ska konsumera ett godtyckligt antal kommandoradsargument. Det är här det blir knepigt att skriva återuppringningar; det täcks senare i detta avsnitt.

optparse skickar alltid fyra specifika argument till din återuppringning, och den skickar bara ytterligare argument om du anger dem via callback_args och callback_kwargs. Den minimala signaturen för en callback-funktion är alltså:

def my_callback(option, opt, värde, parser):

De fyra argumenten till en callback beskrivs nedan.

Det finns flera andra optionsattribut som du kan ange när du definierar ett callback-alternativ:

typ

har sin vanliga betydelse: som med åtgärderna "store" eller "append" instruerar den optparse att ta emot ett argument och konvertera det till type. Istället för att lagra det konverterade värdet någonstans, skickar optparse det till din återuppringningsfunktion.

nargs

har också sin vanliga betydelse: om den anges och > 1, kommer optparse att använda nargs-argument, som alla måste kunna konverteras till type. Den skickar sedan en tupel av konverterade värden till din callback.

callback_args

en tupel av extra positionella argument som ska skickas till återuppringningen

callback_kwargs

en ordbok med extra nyckelordsargument som ska skickas till återuppringningen

Hur återuppringningar anropas

Alla callbacks anropas på följande sätt:

func(option, opt_str, värde, parser, *args, **kwargs)

där

alternativ

är den Option-instans som anropar återuppringningen

opt_str

är den alternativsträng som sågs på kommandoraden och som utlöser återuppringningen. (Om ett förkortat långt alternativ användes kommer opt_str att vara den fullständiga, kanoniska alternativsträngen - t.ex. om användaren anger --foo på kommandoraden som en förkortning för --foobar kommer opt_str att vara "--foobar".)

värde

är argumentet till detta alternativ sett på kommandoraden. optparse förväntar sig bara ett argument om type är inställd; typen av value kommer att vara den typ som impliceras av alternativets typ. Om type för detta alternativ är None (inget argument förväntas), kommer value att vara None. Om nargs > 1, kommer value att vara en tupel av värden av lämplig typ.

parser

är OptionParser-instansen som driver det hela, främst användbar eftersom du kan komma åt några andra intressanta data via dess instansattribut:

parser.largs

den aktuella listan med kvarvarande argument, dvs. argument som har använts men som varken är alternativ eller alternativargument. Känn dig fri att modifiera parser.largs, t.ex. genom att lägga till fler argument. (Denna lista kommer att bli args, det andra returvärdet av parse_args().)

parser.rargs

den aktuella listan med återstående argument, dvs. med opt_str och value (om tillämpligt) borttagna, och endast argumenten efter dem finns kvar. Modifiera gärna parser.rargs, t.ex. genom att använda fler argument.

parser.värden

objektet där alternativvärdena lagras som standard (en instans av optparse.OptionValues). Detta gör att återuppringningar kan använda samma mekanism som resten av optparse för att lagra alternativvärden; du behöver inte röra runt med globaler eller stängningar. Du kan också komma åt eller ändra värdet/värdena för alla alternativ som redan finns på kommandoraden.

args

är en tupel av godtyckliga positionella argument som tillhandahålls via alternativattributet callback_args.

kwargs

är en ordbok med godtyckliga nyckelordsargument som tillhandahålls via callback_kwargs.

Felmeddelanden i en callback

Återkallningsfunktionen bör ge upphov till OptionValueError om det finns några problem med alternativet eller dess argument. optparse fångar upp detta och avslutar programmet genom att skriva ut det felmeddelande du anger till stderr. Meddelandet bör vara tydligt, kortfattat och korrekt och nämna det felaktiga alternativet. Annars kommer användaren att ha svårt att förstå vad han eller hon gjorde för fel.

Exempel på återuppringning 1: trivial återuppringning

Här är ett exempel på ett callback-alternativ som inte tar några argument, och som bara registrerar att alternativet sågs:

def record_foo_seen(option, opt_str, värde, parser):
    parser.värden.saw_foo = True

parser.add_option("--foo", action="callback", callback=record_foo_seen)

Naturligtvis kan du göra det med åtgärden "store_true".

Exempel på återuppringning 2: kontrollera alternativ order

Här är ett lite mer intressant exempel: registrera det faktum att -a ses, men spräng om det kommer efter -b i kommandoraden.

def check_order(option, opt_str, värde, parser):
    if parser.värden.b:
        raise OptionValueError("kan inte använda -a efter -b")
    parser.värden.a = 1
...
parser.add_option("-a", action="callback", callback=check_order)
parser.add_option("-b", action="store_true", dest="b")

Återkallelse exempel 3: kontrollera alternativ ordning (generaliserad)

Om du vill återanvända denna återuppringning för flera liknande alternativ (ställa in en flagga, men spränga om -b redan har setts), behöver den lite arbete: felmeddelandet och flaggan som det ställer in måste generaliseras:

def check_order(option, opt_str, värde, parser):
    if parser.värden.b:
        raise OptionValueError("kan inte använda %s efter -b" % opt_str)
    setattr(parser.värden, option.dest, 1)
...
parser.add_option("-a", action="callback", callback=check_order, dest='a')
parser.add_option("-b", action="store_true", dest="b")
parser.add_option("-c", action="callback", callback=check_order, dest='c')

Exempel på återuppringning 4: kontrollera godtyckligt tillstånd

Naturligtvis kan du lägga in vilket villkor som helst där - du är inte begränsad till att kontrollera värdena för redan definierade alternativ. Om du till exempel har alternativ som inte ska anropas när månen är full, behöver du bara göra så här:

def check_moon(option, opt_str, värde, parser):
    if is_moon_full():
        raise OptionValueError("%s alternativet ogiltigt när månen är full"
                               % opt_str)
    setattr(parser.värden, option.dest, 1)
...
parser.add_option("--foo",
                  action="återuppringning", återuppringning=check_moon, dest="foo")

(Definitionen av is_moon_full() lämnas som en övning för läsaren)

Exempel på återuppringning 5: fasta argument

Saker och ting blir lite mer intressanta när du definierar callback-alternativ som tar ett fast antal argument. Att ange att ett callback-alternativ tar argument liknar att definiera ett "store" eller "append"-alternativ: om du definierar type, så tar alternativet ett argument som måste kunna konverteras till den typen; om du vidare definierar nargs, så tar alternativet nargs-argument.

Här är ett exempel som bara emulerar standardåtgärden "store":

def store_value(option, opt_str, värde, parser):
    setattr(parser.values, option.dest, värde)
...
parser.add_option("--foo",
                  action="återuppringning", återuppringning=store_value,
                  type="int", nargs=3, dest="foo")

Observera att optparse tar hand om att konsumera 3 argument och konvertera dem till heltal åt dig; allt du behöver göra är att lagra dem. (Eller vad som helst; uppenbarligen behöver du inte en callback för det här exemplet)

Callback exempel 6: variabelargument

Det blir lite knepigt när du vill att ett alternativ ska ta ett variabelt antal argument. I det här fallet måste du skriva en callback, eftersom optparse inte har några inbyggda funktioner för det. Och du måste hantera vissa svårigheter med konventionell Unix kommandoradsanalys som optparse normalt hanterar åt dig. I synnerhet bör återuppringningar implementera de konventionella reglerna för nakna -- och - argument:

  • antingen -- eller - kan vara alternativargument

  • bara -- (om det inte är argumentet till något alternativ): stoppa kommandoradsbehandlingen och kasta bort --

  • bare - (om det inte är argumentet till något alternativ): stoppa kommandoradsbehandlingen men behåll - (lägg till det i parser.largs)

Om du vill ha ett alternativ som tar ett variabelt antal argument finns det flera subtila, knepiga frågor att oroa sig för. Den exakta implementeringen du väljer kommer att baseras på vilka avvägningar du är villig att göra för din applikation (vilket är anledningen till att optparse inte stöder den här typen av saker direkt).

Här är ändå ett försök till en callback för ett alternativ med variabla argument:

def vararg_callback(option, opt_str, värde, parser):
    assert värdet är None
    värde = []

    def floatable(str):
        try:
            float(str)
            returnerar sant
        utom ValueError:
            return False

    för arg i parser.rargs:
        # stoppa på --foo som alternativ
        if arg[:2] == "--" and len(arg) > 2:
            break
        # stoppa på -a, men inte på -3 eller -3.0
        if arg[:1] == "-" and len(arg) > 1 and not floatable(arg):
            break
        värde.append(arg)

    del parser.rargs[:len(värde)]
    setattr(parser.värden, option.dest, värde)

...
parser.add_option("-c", "--callback", dest="vararg_attr",
                  action="återuppringning", återuppringning=vararg_callback)

Utökning av optparse

Eftersom de två viktigaste faktorerna som styr hur optparse tolkar kommandoradsalternativ är åtgärden och typen för varje alternativ, är den mest sannolika inriktningen för utvidgning att lägga till nya åtgärder och nya typer.

Lägga till nya typer

För att lägga till nya typer måste du definiera din egen underklass av optparse Option-klassen. Denna klass har ett par attribut som definierar optparse s typer: TYPES och TYPE_CHECKER.

Option.TYPES

En tupel av typnamn; i din subklass definierar du helt enkelt en ny tupel TYPES som bygger på standardtupeln.

Option.TYPE_CHECKER

En ordbok som mappar typnamn till typkontrollfunktioner. En typkontrollfunktion har följande signatur:

def check_mytype(option, opt, värde)

där option är en instans av Option, opt är en optionssträng (t.ex. -f) och value är strängen från kommandoraden som måste kontrolleras och konverteras till önskad typ. check_mytype() bör returnera ett objekt av den hypotetiska typen mytype. Det värde som returneras av en typkontrollfunktion hamnar i OptionValues-instansen som returneras av OptionParser.parse_args(), eller skickas till en callback som parametern value.

Din typkontrollfunktion bör ge upphov till OptionValueError om den stöter på några problem. OptionValueError tar ett enda strängargument, som skickas som det är till OptionParser:s error()-metod, som i sin tur lägger till programnamnet och strängen "error:" och skriver ut allt till stderr innan processen avslutas.

Här är ett fånigt exempel som visar hur man lägger till en "complex" alternativtyp för att analysera komplexa tal i Python-stil på kommandoraden. (Det här är ännu fånigare än det brukade vara, eftersom optparse 1.3 lade till inbyggt stöd för komplexa tal, men strunt samma)

Först den nödvändiga importen:

från copy import kopiera
från optparse import Option, OptionValueError

Du måste definiera din typkontroll först, eftersom det hänvisas till senare (i TYPE_CHECKER klassattributet i din Option-underklass):

def check_complex(option, opt, värde):
    försök:
        return komplex(värde)
    except ValueError:
        raise OptionValueError(
            "option %s: ogiltigt komplext värde: %r" % (opt, värde))

Slutligen kan Option-underklassen:

klass MyOption (Option):
    TYPES = Option.TYPES + ("komplex",)
    TYPE_CHECKER = copy(Option.TYPE_CHECKER)
    TYPE_CHECKER["complex"] = check_complex

(Om vi inte gjorde en copy() av Option.TYPE_CHECKER, skulle vi sluta med att modifiera attributet TYPE_CHECKER i optparses Option-klass. Eftersom det här är Python finns det inget som hindrar dig från att göra det, förutom gott uppförande och sunt förnuft)

Nu är det klart! Nu kan du skriva ett skript som använder den nya optionstypen precis som alla andra optparse -baserade skript, förutom att du måste instruera din OptionParser att använda MyOption i stället för Option:

parser = OptionParser(option_class=MyOption)
parser.add_option("-c", type="complex")

Alternativt kan du skapa din egen alternativlista och skicka den till OptionParser; om du inte använder add_option() på ovanstående sätt behöver du inte tala om för OptionParser vilken alternativklass som ska användas:

option_list = [MyOption("-c", action="store", type="complex", dest="c")]
parser = OptionParser(option_list=option_list)

Lägga till nya åtgärder

Att lägga till nya åtgärder är lite knepigare, eftersom du måste förstå att optparse har ett par klassificeringar för åtgärder:

”lagra” åtgärder

åtgärder som resulterar i att optparse lagrar ett värde till ett attribut i den aktuella OptionValues-instansen; dessa alternativ kräver att ett dest-attribut tillhandahålls till Option-konstruktören.

”typade” åtgärder

åtgärder som tar ett värde från kommandoraden och förväntar sig att det ska vara av en viss typ; eller snarare en sträng som kan konverteras till en viss typ. Dessa alternativ kräver ett type-attribut till Option-konstruktören.

Dessa är överlappande uppsättningar: vissa standard ”store”-åtgärder är "store", "store_const", "append" och "count", medan standard ”typed”-åtgärder är "store", "append" och "callback".

När du lägger till en åtgärd måste du kategorisera den genom att lista den i minst ett av följande klassattribut för Option (alla är listor med strängar):

Option.ACTIONS

Alla åtgärder måste listas i ACTIONS.

Option.STORE_ACTIONS

”Store”-åtgärder är dessutom listade här.

Option.TYPED_ACTIONS

”typade” åtgärder listas dessutom här.

Option.ALWAYS_TYPED_ACTIONS

Åtgärder som alltid tar en typ (d.v.s. vars alternativ alltid tar ett värde) listas dessutom här. Den enda effekten av detta är att optparse tilldelar standardtypen, "string", till alternativ utan explicit typ vars åtgärd listas i ALWAYS_TYPED_ACTIONS.

För att faktiskt kunna implementera din nya åtgärd måste du åsidosätta Options take_action()-metod och lägga till ett fall som känner igen din åtgärd.

Låt oss till exempel lägga till en "extend"-åtgärd. Detta liknar standardåtgärden "append", men i stället för att ta ett enda värde från kommandoraden och lägga till det i en befintlig lista, tar "extend" flera värden i en enda kommaseparerad sträng och utökar en befintlig lista med dem. Det vill säga, om --names är ett "extend"-alternativ av typen "string", kommer kommandoraden

--namn=foo,bar --namn blah --namn ding,dong

skulle resultera i en lista

["foo", "bar", "blah", "ding", "dong"]

Återigen definierar vi en underklass av Option:

klass MyOption(Option):

    ACTIONS = Option.ACTIONS + ("extend",)
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
    ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

    def take_action(self, action, dest, opt, value, values, parser):
        if action == "extend":
            lvalue = värde.split(",")
            values.ensure_value(dest, []).extend(lvalue)
        annat:
            Option.take_action(
                self, action, dest, opt, värde, värden, parser)

Funktioner av betydelse:

  • "extend" både förväntar sig ett värde på kommandoraden och lagrar det värdet någonstans, så det går in i både STORE_ACTIONS och TYPED_ACTIONS.

  • för att säkerställa att optparse tilldelar standardtypen "string" till "extend"-åtgärder, lägger vi till "extend"-åtgärden i ALWAYS_TYPED_ACTIONS också.

  • MyOption.take_action() implementerar bara denna enda nya åtgärd och lämnar tillbaka kontrollen till Option.take_action() för standardåtgärderna i optparse.

  • values är en instans av klassen optparse_parser.Values, som tillhandahåller den mycket användbara metoden ensure_value(). ensure_value() är i huvudsak getattr() med en säkerhetsventil; den kallas som

    values.ensure_value(attr, värde)
    

    Om attributet attr i values inte existerar eller är None, sätter ensure_value() det först till value och returnerar sedan value. Detta är mycket praktiskt för åtgärder som "extend", "append" och "count", som alla ackumulerar data i en variabel och förväntar sig att variabeln ska vara av en viss typ (en lista för de två första, ett heltal för den senare). Att använda ensure_value() innebär att skript som använder din åtgärd inte behöver oroa sig för att ställa in ett standardvärde för alternativdestinationerna i fråga; de kan bara lämna standardvärdet som None och ensure_value() kommer att ta hand om att få det rätt när det behövs.

Undantag

exception optparse.OptionError

Utlöses om en Option-instans skapas med ogiltiga eller inkonsekventa argument.

exception optparse.OptionConflictError

Uppstår om motstridiga alternativ läggs till i en OptionParser.

exception optparse.OptionValueError

Utlöses om ett ogiltigt alternativvärde påträffas på kommandoraden.

exception optparse.BadOptionError

Utlöses om ett ogiltigt alternativ anges på kommandoraden.

exception optparse.AmbiguousOptionError

Utlöses om ett tvetydigt alternativ skickas på kommandoraden.