prompt_toolkit是一个python库,用于构建命令行工具和终端应用。其官网介绍如下,
prompt_toolkit is a library for building powerful interactive command line and terminal applications in Python.
安装命令如下,
pip install prompt_toolkit
PS:本文写作时prompt_toolkit版本是3.0.43
本文讲述如何使用prompt_toolkit 3.x版本来构建交互式命令行工具,参考文档是官方教程
一 基本命令行
首先构建一个基本命令行,
from prompt_toolkit import PromptSession
if __name__ == "__main__":
session = PromptSession()
while True:
user_input = session.prompt("> ")
print(user_input)
这里没有使用prompt_toolkit.prompt,而是prompt_toolkit.PromptSession,有2个优点:
-
PromptSession可以自动开启历史功能,prompt则需要配置参数
-
在多次输入情况下,prompt的参数需要传递多次,也就是每次都要使用prompt创建对象并传参,而PromptSession可以只传递一次,就是传给PromptSession(),
from prompt_toolkit import PromptSession if __name__ == "__main__": session = PromptSession('> ') # 参数传给PromptSession(),不需要在while循环里给PromptSession的prompt方法传参了 while True: user_input = session.prompt() print(user_input)
当然也可以传给PromptSession的prompt()方法
可以看出PromptSession更加方便好用。
二 开启补全功能
一般来说,命令行下可输入的有效命令都是一堆固定值,所以当我们输入命令的一部分时,希望能给出补全提示,代码如下,
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
if __name__ == "__main__":
mycompleter = WordCompleter(['A1', 'A2', 'A3', 'B1', 'B11'])
session = PromptSession('> ', completer=mycompleter)
while True:
user_input = session.prompt()
print(user_input)
代码里使用prompt_toolkit.completion中的WordCompleter来存入命令列表,并作为参数传递给PromptSession()
运行后输入A,可以看到会自动弹出允许的命令列表,然后使用上下键来选择需要的命令并回车,
三 设置prompt的颜色
默认prompt的颜色是这种白色,有时希望是其它颜色,
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.styles import Style
if __name__ == "__main__":
mystyle = Style.from_dict({
# User input (default text).
'': '#ff0066',
# Prompt.
'pound': '#00aa00', # 通过pound来进行关联,可以改成别的名字
})
message = [
('class:pound', '> '), # pound对应'>'
]
mycompleter = WordCompleter(['A1', 'A2', 'A3', 'B1', 'B11'])
session = PromptSession(message, style=mystyle, completer=mycompleter)
while True:
user_input = session.prompt()
print(user_input)
运行后如下,
可以看到,不仅修改了prompt的颜色,同时也修改了输入字符的颜色
四 设置光标
前面的例子可以看出,默认的光标是不动的,有时希望光标可以闪烁,表示程序正在运行,那么可以修改如下,
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.styles import Style
from prompt_toolkit.cursor_shapes import CursorShape
if __name__ == "__main__":
mystyle = Style.from_dict({
# User input (default text).
'': '#ff0066',
# Prompt.
'pound11': '#00aa00',
})
message = [
('class:pound11', '> '),
]
mycompleter = WordCompleter(['A1', 'A2', 'A3', 'B1', 'B11'])
session = PromptSession(message, style=mystyle, completer=mycompleter, cursor=CursorShape.BLINKING_BEAM)
while True:
user_input = session.prompt()
print(user_input)
代码里使用了prompt_toolkit.cursor_shapes里的CursorShape
运行后可以看出光标在闪烁。
五 优雅处理Ctrl+C和其它按键
前面的例子运行时,我们按Ctrl+C结束程序都会打印一堆信息,看上去很不优雅,这里对代码进行如下修改,
import sys
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.styles import Style
from prompt_toolkit.cursor_shapes import CursorShape
from prompt_toolkit.key_binding import KeyBindings
bindings = KeyBindings()
@bindings.add('c-c')
def _(event):
" Exit when `ctrl-c` is pressed. "
event.app.exit()
if __name__ == "__main__":
mystyle = Style.from_dict({
# User input (default text).
'': '#ff0066',
# Prompt.
'pound11': '#00aa00',
})
message = [
('class:pound11', '> '),
]
mycompleter = WordCompleter(['A1', 'A2', 'A3', 'B1', 'B11'])
session = PromptSession(message, key_bindings=bindings, style=mystyle, completer=mycompleter, cursor=CursorShape.BLINKING_BEAM)
while True:
user_input = session.prompt()
if user_input is not None:
print(user_input)
else:
break
sys.exit(0)
这里使用了prompt_toolkit.key_binding里的KeyBindings,对按键事件进行处理,代码里对Ctrl+C进行处理
如果想对某些按键进行特殊处理,例如"[",那么可以仿照着进行修改,
import sys
from prompt_toolkit import PromptSession
from prompt_toolkit.completion import WordCompleter
from prompt_toolkit.styles import Style
from prompt_toolkit.cursor_shapes import CursorShape
from prompt_toolkit.key_binding import KeyBindings
from prompt_toolkit.application import run_in_terminal
bindings = KeyBindings()
@bindings.add('c-c')
def _(event):
" Exit when `ctrl-c` is pressed. "
event.app.exit()
@bindings.add('[')
def _(event):
def print_hello():
print('hello world')
run_in_terminal(print_hello)
if __name__ == "__main__":
mystyle = Style.from_dict({
# User input (default text).
'': '#ff0066',
# Prompt.
'pound11': '#00aa00',
})
message = [
('class:pound11', '> '),
]
mycompleter = WordCompleter(['A1', 'A2', 'A3', 'B1', 'B11'])
session = PromptSession(message, key_bindings=bindings, style=mystyle, completer=mycompleter, cursor=CursorShape.BLINKING_BEAM)
while True:
user_input = session.prompt()
if user_input is not None:
print(user_input)
else:
break
sys.exit(0)
对于’[‘的处理,使用了run_in_terminal()函数,这个函数可以保证按下’['之后还能继续在命令程序下,不会退出,不过这个函数需要传递一个参数,这个参数是函数。
六 总结
本文讲述了如何使用prompt_toolkit来构建交互式命令行工具,实现了一些常用功能。可以看出prompt_toolkit功能非常强大,其实际功能远不止本文介绍的,详情可以看官方文档。