使用prompt_toolkit构建交互式命令行工具

prompt_toolkit是一个python库,用于构建命令行工具和终端应用。其官网介绍如下,

prompt_toolkit is a library for building powerful interactive command line and terminal applications in Python.

安装命令如下,

bash 复制代码
pip install prompt_toolkit

PS:本文写作时prompt_toolkit版本是3.0.43

本文讲述如何使用prompt_toolkit 3.x版本来构建交互式命令行工具,参考文档是官方教程


一 基本命令行

首先构建一个基本命令行,

python 复制代码
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(),

    python 复制代码
    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更加方便好用。


二 开启补全功能

一般来说,命令行下可输入的有效命令都是一堆固定值,所以当我们输入命令的一部分时,希望能给出补全提示,代码如下,

python 复制代码
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的颜色是这种白色,有时希望是其它颜色,

python 复制代码
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的颜色,同时也修改了输入字符的颜色


四 设置光标

前面的例子可以看出,默认的光标是不动的,有时希望光标可以闪烁,表示程序正在运行,那么可以修改如下,

python 复制代码
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结束程序都会打印一堆信息,看上去很不优雅,这里对代码进行如下修改,

python 复制代码
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进行处理

如果想对某些按键进行特殊处理,例如"[",那么可以仿照着进行修改,

python 复制代码
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功能非常强大,其实际功能远不止本文介绍的,详情可以看官方文档。

相关推荐
消失在人海中5 分钟前
大模型基础:基本概念、Prompt、RAG、Agent及多模态
大模型·prompt
数据龙傲天7 分钟前
1688商品API接口:电商数据自动化的新引擎
java·大数据·sql·mysql
带带老表学爬虫35 分钟前
java数据类型转换和注释
java·开发语言
千里码aicood42 分钟前
【2025】springboot教学评价管理系统(源码+文档+调试+答疑)
java·spring boot·后端·教学管理系统
彭于晏6891 小时前
Android广播
android·java·开发语言
程序员-珍1 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
2401_857297912 小时前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
福大大架构师每日一题2 小时前
23.1 k8s监控中标签relabel的应用和原理
java·容器·kubernetes
金灰2 小时前
HTML5--裸体回顾
java·开发语言·前端·javascript·html·html5
菜鸟一皓2 小时前
IDEA的lombok插件不生效了?!!
java·ide·intellij-idea