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

相关推荐
customer0836 分钟前
【开源免费】基于SpringBoot+Vue.JS体育馆管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
Miketutu1 小时前
Spring MVC消息转换器
java·spring
乔冠宇1 小时前
Java手写简单Merkle树
java·区块链·merkle树
LUCIAZZZ2 小时前
简单的SQL语句的快速复习
java·数据库·sql
komo莫莫da3 小时前
寒假刷题Day19
java·开发语言
S-X-S3 小时前
算法总结-数组/字符串
java·数据结构·算法
linwq84 小时前
设计模式学习(二)
java·学习·设计模式
AIGC大时代4 小时前
对比DeepSeek、ChatGPT和Kimi的学术写作关键词提取能力
论文阅读·人工智能·chatgpt·数据分析·prompt
桦说编程4 小时前
CompletableFuture 超时功能有大坑!使用不当直接生产事故!
java·性能优化·函数式编程·并发编程
@_@哆啦A梦4 小时前
Redis 基础命令
java·数据库·redis