cmd — Stöd för linjeorienterade kommandotolkar

Källkod: Lib/cmd.py


Klassen Cmd tillhandahåller ett enkelt ramverk för att skriva linjeorienterade kommandotolkar. Dessa är ofta användbara för testverktyg, administrativa verktyg och prototyper som senare kommer att förpackas i ett mer sofistikerat gränssnitt.

class cmd.Cmd(completekey='tab', stdin=None, stdout=None)

En Cmd-instans eller underklass-instans är ett linjeorienterat tolkningsramverk. Det finns ingen bra anledning att instansiera Cmd själv; snarare är den användbar som en superklass av en tolkklass som du definierar själv för att ärva Cmds metoder och kapsla in åtgärdsmetoder.

Det valfria argumentet completekey är namnet readline på en kompletteringsnyckel; standardvärdet är Tab. Om completekey inte är None och readline är tillgängligt, sker kommandokomplettering automatiskt.

Standardvärdet, 'tab', behandlas speciellt så att det hänvisar till Tab-tangenten på varje readline.backend. Mer specifikt, om readline.backend är editline, kommer Cmd att använda '^I' istället för 'tab'. Observera att andra värden inte behandlas på detta sätt och kanske bara fungerar med en specifik backend.

De valfria argumenten stdin och stdout anger de in- och utdatafilobjekt som Cmd-instansen eller underklassinstansen ska använda för in- och utdata. Om de inte anges kommer de som standard att vara sys.stdin och sys.stdout.

Om du vill att en viss stdin ska användas, se till att sätta instansens attribut use_rawinput till False, annars kommer stdin att ignoreras.

Ändrad i version 3.13: completekey='tab' ersätts av '^I' för editline.

Cmd-objekt

En Cmd-instans har följande metoder:

Cmd.cmdloop(intro=None)

Upprepa en uppmaning, acceptera inmatning, analysera ett initialt prefix från den mottagna inmatningen och skicka till åtgärdsmetoder och skicka resten av raden till dem som argument.

Det valfria argumentet är en banner eller introsträng som ska visas före den första prompten (detta åsidosätter klassattributet intro).

Om modulen readline laddas, kommer inmatningen automatiskt att ärva bash -liknande historielistredigering (t.ex. Control-P rullar tillbaka till det senaste kommandot, Control-N framåt till nästa, Control-F flyttar markören till höger på ett icke-destruktivt sätt, Control-B flyttar markören till vänster på ett icke-destruktivt sätt, etc.).

En fil som slutar vid inmatning skickas tillbaka som strängen 'EOF'.

En tolkinstans känner igen kommandonamnet foo om och endast om det har en metod do_foo`(). Som ett specialfall skickas en rad som börjar med tecknet '?' till metoden do_help(). Som ett annat specialfall skickas en rad som börjar med tecknet '!' till metoden do_shell() (om en sådan metod är definierad).

Denna metod returneras när metoden postcmd() returnerar ett sant värde. Argumentet stop till postcmd() är returvärdet från kommandots motsvarande metod do_*().

Om komplettering är aktiverat kommer kommandon att kompletteras automatiskt, och komplettering av kommandon görs genom att anropa complete_foo() med argumenten text, line, begidx och endidx. text är det strängprefix som vi försöker matcha: alla returnerade matchningar måste börja med det. rad är den aktuella inmatningsraden med inledande blanksteg borttagna, begidx och endidx är start- och slutindex för prefixtexten, som kan användas för att ge olika komplettering beroende på vilken position argumentet befinner sig i.

Cmd.do_help(arg)

Alla subklasser av Cmd ärver en fördefinierad do_help(). Denna metod, som anropas med argumentet 'bar', anropar motsvarande metod help_bar(), och om den inte finns, skriver ut dokumentsträngen för do_bar(), om den finns tillgänglig. Utan argument listar do_help() alla tillgängliga hjälpämnen (det vill säga alla kommandon med motsvarande help_*()-metoder eller kommandon som har dokumentsträngar), och listar även eventuella odokumenterade kommandon.

Cmd.onecmd(str)

Tolkar argumentet som om det hade skrivits in som svar på prompten. Detta kan åsidosättas, men bör normalt inte behövas; se metoderna precmd() och postcmd() för användbara exekveringskrokar. Returvärdet är en flagga som anger om tolkarens tolkning av kommandon ska stoppas. Om det finns en do_*()-metod för kommandot str returneras returvärdet för den metoden, annars returneras returvärdet från default()-metoden.

Cmd.emptyline()

Metod som anropas när en tom rad skrivs in som svar på prompten. Om den här metoden inte åsidosätts upprepas det senast angivna kommandot som inte var tomt.

Cmd.default(line)

Metod som anropas på en inmatningsrad när kommandoprefixet inte känns igen. Om denna metod inte åsidosätts skriver den ut ett felmeddelande och returnerar.

Cmd.completedefault(text, line, begidx, endidx)

Metod som anropas för att slutföra en inmatningsrad när ingen kommandospecifik complete_*()-metod finns tillgänglig. Som standard returnerar den en tom lista.

Cmd.columnize(list, displaywidth=80)

Metod för att visa en lista med strängar som en kompakt uppsättning kolumner. Varje kolumn är bara så bred som behövs. Kolumnerna är separerade med två mellanslag för läsbarhetens skull.

Cmd.precmd(line)

Hook-metod som exekveras precis innan kommandoraden line tolkas, men efter att indataprompten har genererats och skickats ut. Denna metod är en stub i Cmd; den existerar för att kunna åsidosättas av underklasser. Returvärdet används som det kommando som kommer att utföras av metoden onecmd(); implementationen av precmd() kan skriva om kommandot eller helt enkelt returnera line oförändrad.

Cmd.postcmd(stop, line)

Hook-metod som exekveras strax efter att ett kommando är färdigt. Denna metod är en stub i Cmd; den existerar för att kunna åsidosättas av underklasser. line är kommandoraden som kördes, och stop är en flagga som anger om körningen skall avslutas efter anropet till postcmd(); detta kommer att vara returvärdet för metoden onecmd(). Returvärdet för denna metod kommer att användas som det nya värdet för den interna flagga som motsvarar stop; om den returnerar false kommer tolkningen att fortsätta.

Cmd.preloop()

Hook-metod som exekveras en gång när cmdloop() anropas. Denna metod är en stub i Cmd; den finns för att åsidosättas av subklasser.

Cmd.postloop()

Hook-metod som exekveras en gång när cmdloop() är på väg att returnera. Denna metod är en stub i Cmd; den existerar för att kunna åsidosättas av subklasser.

Instanser av Cmd-subklasser har vissa offentliga instansvariabler:

Cmd.prompt

Den uppmaning som gavs för att få in synpunkter.

Cmd.identchars

Den teckensträng som accepteras för kommandoprefixet.

Cmd.lastcmd

Det sista icke-tomma kommandoprefixet sett.

Cmd.cmdqueue

En lista med köade inmatningsrader. Listan cmdqueue kontrolleras i cmdloop() när ny indata behövs; om den inte är tom kommer dess element att behandlas i ordning, som om de angetts vid prompten.

Cmd.intro

En sträng som ska användas som intro eller banner. Kan åsidosättas genom att ge metoden cmdloop() ett argument.

Cmd.doc_header

Den rubrik som ska visas om hjälputmatningen har ett avsnitt för dokumenterade kommandon.

Cmd.misc_header

Rubriken som ska visas om hjälputmatningen har ett avsnitt för diverse hjälpämnen (det vill säga om det finns help_*()-metoder utan motsvarande do_*()-metoder).

Cmd.undoc_header

Rubriken som ska visas om hjälpen har ett avsnitt för odokumenterade kommandon (det vill säga om det finns do_*()-metoder utan motsvarande help_*()-metoder).

Cmd.ruler

Det tecken som används för att rita separatorlinjer under rubrikerna i hjälpmeddelanden. Om det är tomt ritas ingen linjal. Standardvärdet är '='.

Cmd.use_rawinput

En flagga, standardvärdet är true. Om true, använder cmdloop() input() för att visa en prompt och läsa nästa kommando; om false, används sys.stdout.write() och sys.stdin.readline(). (Detta innebär att genom att importera readline, på system som stödjer det, kommer tolken automatiskt att stödja Emacs -liknande radredigering och kommandohistorik-tangenttryckningar)

Cmd-exempel

Modulen cmd är främst användbar för att bygga egna skal som låter användaren arbeta interaktivt med ett program.

I det här avsnittet ges ett enkelt exempel på hur du bygger ett skal med hjälp av några av kommandona i modulen turtle.

Grundläggande sköldpaddskommandon som forward() läggs till i en Cmd-underklass med en metod som heter do_forward(). Argumentet konverteras till ett tal och skickas till turtle-modulen. Dokumentsträngen används i hjälpverktyget som tillhandahålls av skalet.

Exemplet innehåller också en grundläggande inspelnings- och uppspelningsfunktion som implementeras med metoden precmd() som ansvarar för att konvertera indata till gemener och skriva kommandona till en fil. Metoden do_playback() läser filen och lägger till de inspelade kommandona i cmdqueue för omedelbar uppspelning:

import cmd, sys
from turtle import *

class TurtleShell(cmd.Cmd):
    intro = 'Welcome to the turtle shell.   Type help or ? to list commands.\n'
    prompt = '(turtle) '
    file = None

    # ----- basic turtle commands -----
    def do_forward(self, arg):
        'Move the turtle forward by the specified distance:  FORWARD 10'
        forward(*parse(arg))
    def do_right(self, arg):
        'Turn turtle right by given number of degrees:  RIGHT 20'
        right(*parse(arg))
    def do_left(self, arg):
        'Turn turtle left by given number of degrees:  LEFT 90'
        left(*parse(arg))
    def do_goto(self, arg):
        'Move turtle to an absolute position with changing orientation.  GOTO 100 200'
        goto(*parse(arg))
    def do_home(self, arg):
        'Return turtle to the home position:  HOME'
        home()
    def do_circle(self, arg):
        'Draw circle with given radius an options extent and steps:  CIRCLE 50'
        circle(*parse(arg))
    def do_position(self, arg):
        'Print the current turtle position:  POSITION'
        print('Current position is %d %d\n' % position())
    def do_heading(self, arg):
        'Print the current turtle heading in degrees:  HEADING'
        print('Current heading is %d\n' % (heading(),))
    def do_color(self, arg):
        'Set the color:  COLOR BLUE'
        color(arg.lower())
    def do_undo(self, arg):
        'Undo (repeatedly) the last turtle action(s):  UNDO'
    def do_reset(self, arg):
        'Clear the screen and return turtle to center:  RESET'
        reset()
    def do_bye(self, arg):
        'Stop recording, close the turtle window, and exit:  BYE'
        print('Thank you for using Turtle')
        self.close()
        bye()
        return True

    # ----- record and playback -----
    def do_record(self, arg):
        'Save future commands to filename:  RECORD rose.cmd'
        self.file = open(arg, 'w')
    def do_playback(self, arg):
        'Playback commands from a file:  PLAYBACK rose.cmd'
        self.close()
        with open(arg) as f:
            self.cmdqueue.extend(f.read().splitlines())
    def precmd(self, line):
        line = line.lower()
        if self.file and 'playback' not in line:
            print(line, file=self.file)
        return line
    def close(self):
        if self.file:
            self.file.close()
            self.file = None

def parse(arg):
    'Convert a series of zero or more numbers to an argument tuple'
    return tuple(map(int, arg.split()))

if __name__ == '__main__':
    TurtleShell().cmdloop()

Här är ett exempel på en session med sköldpaddsskalet som visar hjälpfunktionerna, användning av tomma rader för att upprepa kommandon och den enkla inspelnings- och uppspelningsfunktionen:

Welcome to the turtle shell.   Type help or ? to list commands.

(turtle) ?

Documented commands (type help <topic>):
========================================
bye     color    goto     home  playback  record  right
circle  forward  heading  left  position  reset   undo

(turtle) help forward
Move the turtle forward by the specified distance:  FORWARD 10
(turtle) record spiral.cmd
(turtle) position
Current position is 0 0

(turtle) heading
Current heading is 0

(turtle) reset
(turtle) circle 20
(turtle) right 30
(turtle) circle 40
(turtle) right 30
(turtle) circle 60
(turtle) right 30
(turtle) circle 80
(turtle) right 30
(turtle) circle 100
(turtle) right 30
(turtle) circle 120
(turtle) right 30
(turtle) circle 120
(turtle) heading
Current heading is 180

(turtle) forward 100
(turtle)
(turtle) right 90
(turtle) forward 100
(turtle)
(turtle) right 90
(turtle) forward 400
(turtle) right 90
(turtle) forward 500
(turtle) right 90
(turtle) forward 400
(turtle) right 90
(turtle) forward 300
(turtle) playback spiral.cmd
Current position is 0 0

Current heading is 0

Current heading is 180

(turtle) bye
Thank you for using Turtle