cmd
— Поддержка линейно ориентированных командных интерпретаторов¶
Исходный код: Lib/cmd.py
В Cmd
класс реализует простой фреймворк для создания линейно-
ориентированных командных интерпретаторов. Они часто используются в тестовых
контурах, административных инструментах и прототипах, которые впоследствии будут
упакованы в более сложный интерфейс.
-
class
cmd.
Cmd
(completekey='tab', stdin=None, stdout=None)¶ Cmd
сущность или сущность подкласса линейно-ориентированных интерпретаторов фреймворка. Нет никаких веских оснований для создания экземпляра самогоCmd
; он полезен как суперкласс интерпретатора, реализуемого самостоятельного класса, наследующего методыCmd
и инкапсулирующий методы действия.Необязательный аргумент completekey - это
readline
имя ключа завершения; значение по умолчанию - Tab. Если completekey неNone
иreadline
доступен, автозавершение команды выполняется автоматически.Опциональные аргументы stdin и stdout определяют объекты входного и выходного файла, которые будут использоваться сущностью Cmd или подклассом сущности для входа и выхода. Если не указано, то они по умолчанию будут
sys.stdin
иsys.stdout
.Если нужно передать используемый stdin, убедитесь, что атрибут
use_rawinput
сущности содержит значениеFalse
, в противном случае stdin будет проигнорирован.
Объекты Cmd¶
Сущность Cmd
содержит следующие методы:
-
Cmd.
cmdloop
(intro=None)¶ Повторно выводит приглашение, принемает ввод, анализирует начальный префикс от полученного ввода и направляет к действие методам, передав им оставшуюся часть строки в качестве аргумента.
Необязательный аргумент - это баннер или интро-строка, которые должны быть выданы перед первым запросом (это переопределяется атрибутом
intro
класса).Если модуль
readline
загружен, ввод автоматически наследует bash-подобное редактирование списка истории (например Control-P прокрутка назад к последней команде, Control-N вперед к следующей, Control-F перемещает курсор вправо без разрушения, Control-B перемещает курсор влево без разрушения и т.д.).Конец файла на входе передается обратно в качестве строки
'EOF'
.Сущность интерпретатора распознает имя команды
foo
если и только если она содержит методdo_foo()
. В специальном случае строка, начинающаяся с'?'
символа, отправляется в методdo_help()
. В другом особом случае строка, начинающаяся с'!'
символа, отправляется в методdo_shell()
(если такой метод определен).Этот метод будет возвращать когда
postcmd()
метод возвращает истинное значение. Аргументом stop дляpostcmd()
является возвращение значения из соответствующегоdo_*()
метода команды.Если автозавершение включено, завершение команд выполняется автоматически, а завершение команд args выполняется путем вызова
complete_foo()
с аргументами text, line, begidx и endidx. text - это строка префикс, который мы пытаемся сопоставить: все возвращённые совпадения должны начинаться с него. line является текущей входной строкой с удаленным начальным пробелом, begidx и endidx являются начальными и конечными индексами текста префикса, которые могут быть использованы для обеспечения различных автозавершений в зависимости от того, в какой позиции находится аргумент.Все подклассы
Cmd
наследуют предопределенныйdo_help()
. Этот метод, вызыванный с аргументом'bar'
, вызывает соответствующий методhelp_bar()
, и если это отсутствует, печатает докстрингdo_bar()
, при наличии. Без аргументовdo_help()
перечисляет все доступные разделы справки (то есть все команды с соответствующимиhelp_*()
методами или командами, имеющими докстринги), а также перечисляет любые недокументированные команды.
-
Cmd.
onecmd
(str)¶ Интерпретировать аргумент, как если бы он был напечатан в ответ на приглашение. Это может быть переопределено, но обычно не обязательно; для получения полезной информации см. методы
precmd()
иpostcmd()
. Возвращаемое значение - это флаг, указывающий, должна ли прекращаться интерпретация команд интерпретатора. Если естьdo_*()
метод для команды str, возвращает значение возвращаемого метода, иначе возвращает значение из методаdefault()
.
-
Cmd.
emptyline
()¶ Вызываемый метод при вводе пустой строки в ответ на запрос. Если метод не переопределен, он повторяет последнюю введенную непустую команду.
-
Cmd.
default
(line)¶ Метод, вызываемый во входной строке, если префикс команды не распознан. Если этот метод не переопределен, он печатает сообщение об ошибке и возвращает управление.
-
Cmd.
completedefault
(text, line, begidx, endidx)¶ Метод, вызываемый для завершения входной строки, когда отсутствует специфичный для команды метод
complete_*()
. По умолчанию он возвращает пустой список.
-
Cmd.
precmd
(line)¶ Хук метод выполняемый непосредственно перед интерпретированием line командной строки, но после формирования и выдачи запроса на ввод. Этот метод является заглушкой в
Cmd
и предназначен для возможности переопределения его подклассом. Возвращает значение используемый как команда, выполняемая методonecmd()
; реализацияprecmd()
может переписать команду или просто возвращает line без изменений.
-
Cmd.
postcmd
(stop, line)¶ Хук метод выполняемый сразу после завершения диспетчеризации команды. Этот метод является заглушкой в
Cmd
для реализации возможности переопределения его подклассом. line - командная строка, которая была выполнена, и stop - флаг, который указывает, будет ли выполнение завершено после вызоваpostcmd()
; это будет возвращаемое значение методаonecmd()
. Возвращает значение этого метод будет используемый как новое значение для внутреннего флага, который соответствует stop; возвращение false приведёт к продолжению интерпретации.
-
Cmd.
preloop
()¶ Хук метод выполняемый один раз при вызове
cmdloop()
. Этот метод является заглушкой вCmd
для реализации возможности переопределения его подклассом.
-
Cmd.
postloop
()¶ Хук метод выполняемый один раз, когда
cmdloop()
собирается вернуть результат. Этот метод является заглушкой вCmd
для реализации возможности переопределения его подклассом.
У сущности Cmd
подкласса есть открытые переменные сущности:
-
Cmd.
prompt
¶ Запрос на ввод данных.
-
Cmd.
identchars
¶ Строка символов, принятых для префикса команды.
-
Cmd.
lastcmd
¶ Последний видимый префикс непустой команды.
-
Cmd.
cmdqueue
¶ Список входящих строк в очереди. Список cmdqueue проверяется в
cmdloop()
при необходимости нового ввода; если он является непустым, его элементы будут обрабатываться в порядке, как если бы они были введены в приглашение.
-
Cmd.
intro
¶ Строка релиза в виде приглашения или баннера. Может быть переопределена путём передачи методу
cmdloop()
аргумента.
-
Cmd.
doc_header
¶ Заголовок для вывода справки, содержащий раздел для задокументированных команд.
-
Cmd.
misc_header
¶ Заголовок, выдаваемый в случае, если в выходных данных справки имеется раздел для различных разделов справки (т.е. имеются
help_*()
методы без соответствующегоdo_*()
методы).
-
Cmd.
undoc_header
¶ Заголовок релиза, если выходной документ справки содержит раздел для недокументированных команд (то есть существуют
do_*()
методы без соответствующихhelp_*()
методов).
-
Cmd.
ruler
¶ Символ используемый для рисования линии-разделители под заголовками справочного сообщения. Если пустая, линия-разделитель не прорисовывается. Значение по умолчанию -
'='
.
-
Cmd.
use_rawinput
¶ Флаг, по умолчанию истинна. Если значение равно истина,
cmdloop()
используетinput()
для отображения приглашения и чтения следующей команды; при значении ложь используютсяsys.stdout.write()
иsys.stdin.readline()
. (Это означает, что при импортеreadline
в системах его поддерживающих, интерпретатор автоматически поддерживает Emacs-подобное редактирование строк и нажатие клавиш в журнале команд.)
Пример Cmd¶
Модуль cmd
в основном полезен для создания пользовательских оболочек,
которые позволяют пользователю работать с программой в интерактивном режиме.
В этом разделе представлен простой пример построения оболочки вокруг нескольких
команд модуля turtle
.
Основные команды turtle, такие как forward()
добавлены к Cmd
подкласс с методом do_forward()
. Аргумент преобразуется в число и
отправляется в модуль turtle. Докстринг используется в утилите справки,
предоставляемая оболочкой.
Пример также включает в себя основное средство записи и воспроизведения,
реализованное методом precmd()
, которое отвечает за преобразование ввода
в нижний регистр и запись команд в файл. do_playback()
метод считывает файл
и добавляет записанные команды в cmdqueue
для немедленного воспроизведения:
import cmd, sys
from turtle import *
class TurtleShell(cmd.Cmd):
intro = 'Добро пожаловать в черепаший шелл. Введите help или ? для получения перечня команд.\n'
prompt = '(turtle) '
file = None
# ----- базовые черепашьи команды -----
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
# ----- запись и воспроизведение -----
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):
'Преобразовать последовательность из нулей или больших чисел в кортеж аргумента'
return tuple(map(int, arg.split()))
if __name__ == '__main__':
TurtleShell().cmdloop()
Вот пример сеанса с черепашьей оболочкой, показывающей функции справки, используя пустые строки для повторения команд, а также простую запись и средство воспроизведения:
Добро пожаловать в черепаший шелл. Введите help или ? для получения перечня команд.\n
(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