我想创建一个带有项目选择界面的 Python CLI,允许用户从列表中选择项目。比如:
Select a fruit (up/down to select and enter to confirm):
[x] Apple
[ ] Banana
[ ] Orange
我希望用户能够使用向上/向下箭头更改他们的选择,然后按
Enter
进行确认。
是否存在具有此功能的 Python 模块?我尝试搜索但找不到我想要的东西。
select-shell Node.js 包正是我想要的。
pick Python 模块 可以实现我想要的功能,但它使用了curses 并打开了一个简单的GUI。我想避免创建 GUI 并将所有输出保留在终端中:这可能需要更新显示到终端的行。
我目前正在使用 click,但我不相信它支持此功能。我不确定如何使用
cmd
/readline
来实现这种功能,并且希望有任何见解。
经过一番搜索,我找到了两个满足我需求的库!
第一个是 python-inquirer,它是 Inquirer.js 的 Python 端口,是 Yeoman 等项目使用的 CLI 库。我发现这个库有一个非常好的 API(构建在 blessings 之上),但在设计/功能方面缺乏完善。
第二个(我将使用的)是 whaaaaat,Inquirer 的另一个 Python 端口。这个库提供的功能更接近原始的 Inquirer.js,并且正是我所需要的。然而,该 API 不如 python-inquirer 干净。
示例:
python-inquirer
示例:
from pprint import pprint
import inquirer
questions = [
inquirer.List(
"size",
message="What size do you need?",
choices=["Jumbo", "Large", "Standard", "Medium", "Small", "Micro"],
),
]
answers = inquirer.prompt(questions)
pprint(answers)
whaaaaat
示例:
from whaaaaat import prompt, print_json, Separator
questions = [
{
"type": "list",
"name": "theme",
"message": "What do you want to do?",
"choices": [
"Order a pizza",
"Make a reservation",
Separator(),
"Ask for opening hours",
{"name": "Contact support", "disabled": "Unavailable at this time"},
"Talk to the receptionist",
],
},
{
"type": "list",
"name": "size",
"message": "What size do you need?",
"choices": ["Jumbo", "Large", "Standard", "Medium", "Small", "Micro"],
"filter": lambda val: val.lower(),
},
]
answers = prompt(questions)
print_json(answers)
对于简单的选择,您可以使用 simple-term-menu 包。它简单、小并且不依赖于其他包。
示例:
from simple_term_menu import TerminalMenu
terminal_menu = TerminalMenu(["entry 1", "entry 2", "entry 3"])
choice_index = terminal_menu.show()
您提到了点击包,并提到您不确定如何实现此功能。似乎选择选项是实现单选题的预期方法。
生成的输出不会像其他答案中提到的其他一些包那样好。然而,click 维护得很好,很活跃,并且可以在 UNIX 和 WIN 上运行——如果您计划发布一个库,这是一个关键参数。
我使用了“调查”模块。您可以在此处键入以过滤选项或使用向上/向下键进行导航:
import survey # pip install survey
colour_list = ['red', 'green', 'blue', 'pink', 'silver', 'magenta']
index = survey.routines.select('Favorite colour? ', options = colour_list, focus_mark = '> ', evade_color = survey.colors.basic('yellow'))
print(f'Answered {index}.')