cmd — Unterstützung für zeilenorientierte Befehlsinterpreter¶
Quellcode: Lib/cmd.py
Die Klasse Cmd bietet ein einfaches Framework für die Erstellung zeilenorientierter Befehlsinterpreter. Diese sind oft nützlich für Testgerüste, Verwaltungs-Tools und Prototypen, die später in eine anspruchsvollere Schnittstelle eingebettet werden.
- class cmd.Cmd(completekey='tab', stdin=None, stdout=None)¶
Eine Instanz oder Unterklasse von
Cmdist ein zeilenorientiertes Interpreter-Framework. Es gibt keinen guten Grund,Cmdselbst zu instanziieren; vielmehr ist es nützlich als Oberklasse einer von Ihnen selbst definierten Interpreter-Klasse, um die Methoden vonCmdzu erben und Aktionsmethoden zu kapseln.Das optionale Argument completekey ist der
readline-Name für eine Vervollständigungstaste; er hat standardmäßig den Wert Tab. Wenn completekey nichtNoneist undreadlineverfügbar ist, erfolgt die Befehlsvervollständigung automatisch.Der Standardwert
'tab'wird speziell behandelt, sodass er sich auf die Tabulator-Taste auf jedemreadline.backendbezieht. Insbesondere wennreadline.backendeditlineist, verwendetCmdstattdessen'^I'anstelle von'tab'. Beachten Sie, dass andere Werte nicht auf diese Weise behandelt werden und möglicherweise nur mit einem bestimmten Backend funktionieren.Die optionalen Argumente stdin und stdout geben die Eingabe- und Ausgabedatei-Objekte an, die die Cmd-Instanz oder Unterklasseninstanz für Eingabe und Ausgabe verwendet. Wenn sie nicht angegeben werden, werden sie standardmäßig zu
sys.stdinundsys.stdout.Wenn Sie möchten, dass ein bestimmtes stdin verwendet wird, stellen Sie sicher, dass das Attribut
use_rawinputder Instanz aufFalsegesetzt ist, andernfalls wird stdin ignoriert.Geändert in Version 3.13:
completekey='tab'wird durch'^I'füreditlineersetzt.
Cmd-Objekte¶
Eine Cmd-Instanz hat die folgenden Methoden
- Cmd.cmdloop(intro=None)¶
Gibt wiederholt eine Eingabeaufforderung aus, nimmt Eingaben entgegen, analysiert ein anfängliches Präfix aus den empfangenen Eingaben und leitet sie an Aktionsmethoden weiter, wobei der Rest der Zeile als Argument übergeben wird.
Das optionale Argument ist eine Banner- oder Intro-Zeichenkette, die vor der ersten Eingabeaufforderung ausgegeben wird (dies überschreibt das Klassenattribut
intro).Wenn das Modul
readlinegeladen ist, erbt die Eingabe automatisch eine **bash**-ähnliche Zeilenbearbeitung mit Verlaufsliste (z. B. Strg-P scrollt zurück zum letzten Befehl, Strg-N vorwärts zum nächsten, Strg-F bewegt den Cursor zerstörungsfrei nach rechts, Strg-B bewegt den Cursor zerstörungsfrei nach links usw.).Ein End-of-File-Signal bei der Eingabe wird als Zeichenkette
'EOF'zurückgegeben.Eine Interpreterinstanz erkennt einen Befehlsnamen
foogenau dann, wenn sie eine Methodedo_foo()hat. Als Sonderfall wird eine Zeile, die mit dem Zeichen'?'beginnt, an die Methodedo_help()weitergeleitet. Als weiterer Sonderfall wird eine Zeile, die mit dem Zeichen'!'beginnt, an die Methodedo_shell()weitergeleitet (falls eine solche Methode definiert ist).Diese Methode kehrt zurück, wenn die Methode
postcmd()einen wahren Wert zurückgibt. Das Argument stop fürpostcmd()ist der Rückgabewert der entsprechendendo_*()-Methode des Befehls.Wenn die Vervollständigung aktiviert ist, werden Befehle automatisch vervollständigt, und die Vervollständigung von Befehlsargumenten erfolgt durch Aufruf von
complete_foo()mit den Argumenten text, line, begidx und endidx. text ist das Zeichenkettenpräfix, das wir abzugleichen versuchen: Alle zurückgegebenen Übereinstimmungen müssen damit beginnen. line ist die aktuelle Eingabezeile mit entfernten führenden Leerzeichen, begidx und endidx sind der Anfangs- und Endindex des Präfixtexts, die verwendet werden könnten, um unterschiedliche Vervollständigungen bereitzustellen, abhängig von der Position des Arguments.
- Cmd.do_help(arg)¶
Alle Unterklassen von
Cmderben eine vordefinierte Methodedo_help(). Diese Methode ruft mit dem Argument'bar'die entsprechende Methodehelp_bar()auf und, falls diese nicht vorhanden ist, gibt die Docstring vondo_bar()aus, falls verfügbar. Ohne Argument listetdo_help()alle verfügbaren Hilfethemen auf (d. h. alle Befehle mit entsprechendenhelp_*()-Methoden oder Befehle mit Docstrings) und listet auch alle undokumentierten Befehle auf.
- Cmd.onecmd(str)¶
Interpretiert das Argument so, als wäre es als Antwort auf die Eingabeaufforderung eingegeben worden. Dies kann überschrieben werden, sollte aber normalerweise nicht erforderlich sein. Siehe die Methoden
precmd()undpostcmd()für nützliche Ausführungshooks. Der Rückgabewert ist ein Flag, das angibt, ob die Interpretation von Befehlen durch den Interpreter gestoppt werden soll. Wenn es einedo_*()-Methode für den Befehl str gibt, wird der Rückgabewert dieser Methode zurückgegeben, andernfalls wird der Rückgabewert der Methodedefault()zurückgegeben.
- Cmd.emptyline()¶
Methode, die aufgerufen wird, wenn eine leere Zeile als Antwort auf die Eingabeaufforderung eingegeben wird. Wenn diese Methode nicht überschrieben wird, wiederholt sie den zuletzt eingegebenen nicht leeren Befehl.
- Cmd.default(line)¶
Methode, die für eine Eingabezeile aufgerufen wird, wenn das Befehlspräfix nicht erkannt wird. Wenn diese Methode nicht überschrieben wird, gibt sie eine Fehlermeldung aus und kehrt zurück.
- Cmd.completedefault(text, line, begidx, endidx)¶
Methode, die aufgerufen wird, um eine Eingabezeile zu vervollständigen, wenn keine Befehl-spezifische
complete_*()-Methode verfügbar ist. Standardmäßig gibt sie eine leere Liste zurück.
- Cmd.columnize(list, displaywidth=80)¶
Methode, die aufgerufen wird, um eine Liste von Zeichenketten als kompakte Spalten anzuzeigen. Jede Spalte ist nur so breit wie nötig. Spalten sind zur besseren Lesbarkeit durch zwei Leerzeichen getrennt.
- Cmd.precmd(line)¶
Hook-Methode, die kurz vor der Interpretation der Befehlszeile line aufgerufen wird, aber nachdem die Eingabeaufforderung generiert und ausgegeben wurde. Diese Methode ist ein Stub in
Cmd; sie existiert, um von Unterklassen überschrieben zu werden. Der Rückgabewert wird als Befehl verwendet, der von der Methodeonecmd()ausgeführt wird; die Implementierung vonprecmd()kann den Befehl umschreiben oder einfach line unverändert zurückgeben.
- Cmd.postcmd(stop, line)¶
Hook-Methode, die kurz nach Abschluss der Befehlsweiterleitung aufgerufen wird. Diese Methode ist ein Stub in
Cmd; sie existiert, um von Unterklassen überschrieben zu werden. line ist die ausgeführte Befehlszeile, und stop ist ein Flag, das angibt, ob die Ausführung nach dem Aufruf vonpostcmd()beendet wird; dies ist der Rückgabewert der Methodeonecmd(). Der Rückgabewert dieser Methode wird als neuer Wert für das interne Flag verwendet, das stop entspricht; die Rückgabe von false bewirkt, dass die Interpretation fortgesetzt wird.
- Cmd.preloop()¶
Hook-Methode, die einmal aufgerufen wird, wenn
cmdloop()aufgerufen wird. Diese Methode ist ein Stub inCmd; sie existiert, um von Unterklassen überschrieben zu werden.
- Cmd.postloop()¶
Hook-Methode, die einmal aufgerufen wird, wenn
cmdloop()kurz vor der Rückgabe steht. Diese Methode ist ein Stub inCmd; sie existiert, um von Unterklassen überschrieben zu werden.
Instanzen von Cmd-Unterklassen haben einige öffentliche Instanzvariablen
- Cmd.prompt¶
Die zur Abfrage von Eingaben ausgegebene Eingabeaufforderung.
- Cmd.identchars¶
Die Zeichenkette von Zeichen, die für das Befehlspräfix akzeptiert werden.
- Cmd.lastcmd¶
Das zuletzt gesehene nicht leere Befehlspräfix.
- Cmd.cmdqueue¶
Eine Liste von eingereihten Eingabezeilen. Die Liste `cmdqueue` wird in
cmdloop()überprüft, wenn neue Eingaben benötigt werden; wenn sie nicht leer ist, werden ihre Elemente der Reihe nach verarbeitet, als wären sie an der Eingabeaufforderung eingegeben worden.
- Cmd.intro¶
Eine Zeichenkette, die als Intro oder Banner ausgegeben wird. Kann durch Übergabe eines Arguments an die Methode
cmdloop()überschrieben werden.
- Cmd.doc_header¶
Die Kopfzeile, die ausgegeben wird, wenn die Hilfeausgabe einen Abschnitt für dokumentierte Befehle enthält.
- Cmd.misc_header¶
Die Kopfzeile, die ausgegeben wird, wenn die Hilfeausgabe einen Abschnitt für verschiedene Hilfethemen enthält (d. h. es gibt
help_*()-Methoden ohne entsprechendedo_*()-Methoden).
- Cmd.undoc_header¶
Die Kopfzeile, die ausgegeben wird, wenn die Hilfeausgabe einen Abschnitt für undokumentierte Befehle enthält (d. h. es gibt
do_*()-Methoden ohne entsprechendehelp_*()-Methoden).
- Cmd.ruler¶
Das Zeichen, das zum Zeichnen von Trennlinien unter den Hilfemeldungskopfzeilen verwendet wird. Wenn leer, wird keine Trennlinie gezeichnet. Standardmäßig ist es
'='.
- Cmd.use_rawinput¶
Ein Flag, das standardmäßig wahr ist. Wenn wahr, verwendet
cmdloop()input(), um eine Eingabeaufforderung anzuzeigen und den nächsten Befehl zu lesen; wenn falsch, werdensys.stdout.write()undsys.stdin.readline()verwendet. (Dies bedeutet, dass durch den Import vonreadlineauf Systemen, die dies unterstützen, der Interpreter automatisch **Emacs**-ähnliche Zeilenbearbeitung und Befehlsverlauf-Tastendrücke unterstützt.)
Cmd-Beispiel¶
Das Modul cmd ist hauptsächlich nützlich zum Erstellen benutzerdefinierter Shells, die es einem Benutzer ermöglichen, interaktiv mit einem Programm zu arbeiten.
Dieser Abschnitt präsentiert ein einfaches Beispiel, wie eine Shell um einige der Befehle des Moduls turtle aufgebaut werden kann.
Grundlegende Turtle-Befehle wie forward() werden zu einer Cmd-Unterklasse mit einer Methode namens do_forward() hinzugefügt. Das Argument wird in eine Zahl umgewandelt und an das Turtle-Modul weitergeleitet. Die Docstring wird im von der Shell bereitgestellten Hilfeprogramm verwendet.
Das Beispiel enthält auch eine einfache Aufzeichnungs- und Wiedergabefunktion, die mit der Methode precmd() implementiert ist, die für die Umwandlung der Eingabe in Kleinbuchstaben und das Schreiben der Befehle in eine Datei verantwortlich ist. Die Methode do_playback() liest die Datei und fügt die aufgezeichneten Befehle der cmdqueue zur sofortigen Wiedergabe hinzu.
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()
Hier ist eine Beispiel-Sitzung mit der Turtle-Shell, die die Hilfefunktionen zeigt, leere Zeilen zur Wiederholung von Befehlen verwendet und die einfache Aufzeichnungs- und Wiedergabefunktion nutzt.
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