Oli*_*ver 5 python python-click
我有一个使用最新点击包的 Python 3.6 脚本。我有很多命令,所以我想移动一些到单独的模块。例如
main.py: root, with commands A and B as children
mylib1.py: commands C and D
mylib2.py: commands E and F
Run Code Online (Sandbox Code Playgroud)
然后在main我想“导入” C 到 F 这样 main 似乎有所有 6 个命令,即所有 6 个都是 root 的孩子。
蛮力是很多维护:
# mylib1.py
@click.command()
def cmd1():
...
...
@click.command()
def cmdN():
...
# main.py
import click
from mylib1 import cmd1, cmd2, ... cmdN
@click.group()
def main(): pass
@main.command()
def main_cmd1(): pass
main.add_command(cmd1)
...
main.add_command(cmdN)
Run Code Online (Sandbox Code Playgroud)
少一点维护(无需管理导入):
# mylib1.py
def add_commands(group):
group.add_command(cmd1)
...
group.add_command(cmdN)
# main.py
import click, mylib
@click.group()
def main(): pass
@main.command()
def main_cmd1(): pass
mylib1.add_commands(main)
main()
Run Code Online (Sandbox Code Playgroud)
但最易于维护的似乎是使用click.CommandCollection,它允许我让它看起来好像一组中的命令实际上在另一个组中:
# mylib1.py
import click
@click.group()
def commands():
pass
@commands.command()
def cmd1():
...
...
@commands.command()
def cmdN():
...
# main.py
import click, mylib1
@click.group()
def main_group(): pass
@main_group.command()
def main_cmd1(): pass
main = click.CommandCollection([main_group, mylib1.commands])
main()
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好,到目前为止没有问题,但文档CommandCollection说这不是“推荐的”:
将多个脚本合并为一个脚本也很有趣。虽然这通常不被推荐,因为它嵌套在另一个下面,但合并方法在某些情况下可能很有用,以获得更好的 shell 体验。
有谁知道“不推荐,因为它嵌套在另一个下面”是什么意思,这种方法可能有什么问题?
来自文档:
点击三点:
命令的任意嵌套
自动生成帮助页面
支持运行时延迟加载子命令
我认为第三点(被认为足够重要,可以列入这个简短的清单),指出了您正在尝试做的事情的最佳方式。
我倾向于click.CommandCollection仅在我不是所有者(无法轻松编辑)时使用某些命令代码。我认为对于您这里的用例,首选解决方案是使用click.MultiCommand. 文档中的描述:
除了使用 click.group() 之外,您还可以构建自己的自定义多命令。当您想要支持从插件延迟加载命令时,这非常有用。
在文档中有一个简单的用法示例,在SO上,在 GitHub 上有一个更复杂的示例,其描述为:
Complex 是构建非常复杂的 cli 应用程序的示例,该应用程序从插件文件夹和其他内容动态加载子命令。
如果您需要避免其他问题CommandCollection,那么 github 上有一个长期存在的错误,标题为:向 CommandCollection 添加组会丢失组选项。
将多个脚本合并到一个脚本中也可能很有趣。虽然通常不建议这样做,因为它会将一个嵌套在另一个之下,但合并方法在某些情况下对于获得更好的 shell 体验可能很有用。
你的问题:
有谁知道“不建议,因为它嵌套在另一个之下”是什么意思,这种方法可能存在一些问题。
我认为这次重写可能会使声明更加清晰。
虽然通常不建议将一个嵌套在另一个之下,但合并方法可以......
我相信这就是我想说的。