调用另一个命令并从提示中获取用户输入
Invoking another command and getting user input from prompt
我正在尝试使用 py-click 构建交互式菜单。基本上只是一个结构:
- 列出当前菜单中的可用命令(使用点击组)
- 向用户显示提示其选择的命令(用户输入 #/cmd 名称)
- 从该选择菜单中调用命令
- 这些命令可能导致另一个菜单或执行应用程序代码
- 然后 return 进入主 menu/previous 菜单,一旦代码具有 运行
我的代码:
import click
@click.group(invoke_without_command=True)
@click.pass_context
def main_group(ctx):
""" Lists all the submenu options available"""
cmds = main_group.list_commands(ctx)
click.echo(f"Available options:")
for idx, cmd_str in enumerate(cmds):
click.echo(f"{idx}:{cmd_str}")
click.echo(f"Now that you know all the options, let's make a selection:")
ctx.invoke(main_group.get_command(ctx, "selection"))
@main_group.command()
@click.option('--next_cmd', prompt='Next command:', help="Enter the number corresponding to the desired command")
@click.pass_context
def selection(ctx, next_cmd):
click.echo(f"You've selected {next_cmd}")
# check that selection is valid
# invoke the desired command
# return to parent previous command
@main_group.command()
def submenu_1():
click.echo('A submenu option ')
@main_group.command()
def submenu_2():
click.echo('Another option')
if __name__ == '__main__':
main_group()
然而,上面的输出是:
Available options:
0:application-code
1:selection
2:submenu-1
3:submenu-2
Now that you know all the options, let's make a selection:
You've selected None
Process finished with exit code 0
基本上选择命令的提示是没有效果的。但是选择命令本身有效,因为如果我直接 运行 它:
if __name__ == '__main__':
# main_group()
selection()
然后系统会提示我进行选择。那么...为什么提示被忽略了?或者是我构建这个问题的方法背后的基本前提,例如点击不是为了那个?
编辑:
浏览了一堆使用该库的 git 回购协议,包括它们 provide 的示例,我无法找到任何构建与我想要的有点相似的结构的库。基本上,构建点击应用程序的范例似乎是执行修改某物状态的操作的孤立命令,而不是通过提供不同选项的菜单进行导航。不是说不可能,但似乎也没有开箱即用的支持。
这个问题没有答案。我在这上面花了更多时间。我在这方面取得了一些进展,但我仍然无法拥有诸如:
Main Menu
- Option 1
- Option 2
- Option 3
- Submenu 1
然后
Submenu 1
- Option 1
- Option 2
- Submenu 2
- Back to Main
等我的结论是点击不是用于此的正确工具。事实上,我不确定替代方案是否一定会让它变得更容易(argparse,docopt,...)。也许要做到这一点,最好的方法就是自己构建一个 class 结构。
或者,采用更接近 shell 或 docker 使用的方法,不用理会任何菜单导航,只需启动作用于申请。
我正在尝试使用 py-click 构建交互式菜单。基本上只是一个结构:
- 列出当前菜单中的可用命令(使用点击组)
- 向用户显示提示其选择的命令(用户输入 #/cmd 名称)
- 从该选择菜单中调用命令
- 这些命令可能导致另一个菜单或执行应用程序代码
- 然后 return 进入主 menu/previous 菜单,一旦代码具有 运行
我的代码:
import click
@click.group(invoke_without_command=True)
@click.pass_context
def main_group(ctx):
""" Lists all the submenu options available"""
cmds = main_group.list_commands(ctx)
click.echo(f"Available options:")
for idx, cmd_str in enumerate(cmds):
click.echo(f"{idx}:{cmd_str}")
click.echo(f"Now that you know all the options, let's make a selection:")
ctx.invoke(main_group.get_command(ctx, "selection"))
@main_group.command()
@click.option('--next_cmd', prompt='Next command:', help="Enter the number corresponding to the desired command")
@click.pass_context
def selection(ctx, next_cmd):
click.echo(f"You've selected {next_cmd}")
# check that selection is valid
# invoke the desired command
# return to parent previous command
@main_group.command()
def submenu_1():
click.echo('A submenu option ')
@main_group.command()
def submenu_2():
click.echo('Another option')
if __name__ == '__main__':
main_group()
然而,上面的输出是:
Available options:
0:application-code
1:selection
2:submenu-1
3:submenu-2
Now that you know all the options, let's make a selection:
You've selected None
Process finished with exit code 0
基本上选择命令的提示是没有效果的。但是选择命令本身有效,因为如果我直接 运行 它:
if __name__ == '__main__':
# main_group()
selection()
然后系统会提示我进行选择。那么...为什么提示被忽略了?或者是我构建这个问题的方法背后的基本前提,例如点击不是为了那个?
编辑: 浏览了一堆使用该库的 git 回购协议,包括它们 provide 的示例,我无法找到任何构建与我想要的有点相似的结构的库。基本上,构建点击应用程序的范例似乎是执行修改某物状态的操作的孤立命令,而不是通过提供不同选项的菜单进行导航。不是说不可能,但似乎也没有开箱即用的支持。
这个问题没有答案。我在这上面花了更多时间。我在这方面取得了一些进展,但我仍然无法拥有诸如:
Main Menu
- Option 1
- Option 2
- Option 3
- Submenu 1
然后
Submenu 1
- Option 1
- Option 2
- Submenu 2
- Back to Main
等我的结论是点击不是用于此的正确工具。事实上,我不确定替代方案是否一定会让它变得更容易(argparse,docopt,...)。也许要做到这一点,最好的方法就是自己构建一个 class 结构。
或者,采用更接近 shell 或 docker 使用的方法,不用理会任何菜单导航,只需启动作用于申请。