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

相关推荐
龙腾-虎跃4 小时前
Docker 一键启动服务合集:Redis、MySQL、Kafka、MinIO、Prometheus 等(网盘转存防失效)
redis·mysql·docker·kafka·prometheus·小龙虾·miniio
马剑威(威哥爱编程)4 小时前
【AI全栈后端12-09】Spring Boot 用流式输出做打字机对话:点下去不再干等
java·人工智能·spring boot·后端
步行cgn4 小时前
Spring 事务传播行为详解
java·数据库·spring
海宇服务4 小时前
零信任架构实战:基于海宇车辆vin码查车辆信息详版构建自动化汽配云仓参配核验网关
java·人工智能·架构·自动化
wno7044 小时前
Spring Boot整合Flyway
java·spring boot·后端
vx_Biye_Design4 小时前
springboot旅游管理系统18006-计算机课程设计、毕业设计
java·spring boot·后端·python·elasticsearch·django·课程设计
Wang's Blog5 小时前
Java 中间件之 RabbitMQ 快速入门: 简单队列模型快速入门
java·中间件·java-rabbitmq
骇客野人5 小时前
Java 开发组件大全覆盖后端主流技术栈(基础、Web、ORM、中间件、微服务、安全、工具、测试、运维、信创适配常用组件)
java·前端·中间件
暖核5 小时前
Redis 从基础到集群实战:数据类型、客户端、高可用架构完整梳理
数据库·redis·架构
2401_888859715 小时前
STM32H733 MPU、AXI、FMC学习
java·开发语言·stm32·spring