Python单击:如何从自定义树对象动态创建命令和选项?

Python单击:如何从自定义树对象动态创建命令和选项?,python,python-click,Python,Python Click,[编辑] 我想从自定义python树对象创建动态命令/参数结构 参考这篇文章,我成功地绑定了以下命令: 目标是使用bashshell提供任意深度的命令,并使用层次结构中的下一级动态填充cli选项卡完成,以及它们的参数帮助(通过字典resolver\u dict提供) 将运行内容 但是: 将运行内容资产块,但不能同时运行内容和资产 我负责蜂巢对象中的所有参数继承,因此我不认为需要像其他帖子中建议的那样,通过点击转发参数 因此,如果content块有一个名为studio\u root的参数,而c

[编辑]

我想从自定义python树对象创建动态命令/参数结构

参考这篇文章,我成功地绑定了以下命令:

目标是使用bashshell提供任意深度的命令,并使用层次结构中的下一级动态填充cli选项卡完成,以及它们的参数帮助(通过字典
resolver\u dict
提供)

将运行
内容

但是:

将运行
内容资产
块,但不能同时运行
内容
资产

我负责
蜂巢
对象中的所有参数继承,因此我不认为需要像其他帖子中建议的那样,通过点击转发参数

因此,如果
content
块有一个名为
studio\u root
的参数,而
content-asset
有一个名为
asset\u name
的参数,那么I在内部将所有参数从父对象转发给其所有子对象。ie
content-asset
将通过
resolver\u dict
已存在
studio\u root
asset\u name
参数。(见下文)

我更接近了。我能够创建/加载具有以下yaml结构的命令和参数:

Yaml结构:

\u内容:
studio\u root:/studio
_资产:
资产名称:larry_boo
但使用以下命令:

蜂窝内容资产——资产名称lulu
我得到以下错误:

$honeycomb内容资产——资产名称lulu
我是“”命令
用法:蜂窝内容资产[OPTIONS]命令[ARGS]。。。
请尝试“蜂巢内容资产--帮助”以获取帮助。
错误:缺少命令。
这里有两个问题

  • 我们可以将命令
    蜂窝内容资产
    视为单个命令的路径。。。不是一连串的命令。我只希望运行最终路径:ie-
    蜂窝内容资产
    应该只运行
    资产
    命令,而不是
    蜂窝内容
    块。由于单击组是嵌套的,这可能需要对调用的命令进行更高级别的控制?在这种情况下,它似乎首先运行(
    蜂窝内容
    ),然后在
    蜂窝内容资产
    命令上失败
  • 我假设“缺少的命令”是
    蜂窝内容资产
    命令,但应该是:
    print('我是“命令”)
    ,缺少哪个
代码如下:

DATA_PATH='{}/configs/hive.yaml'.格式(pathlib.PATH(_文件__.parent.parent)
@单击。组()
@单击。传递上下文
def cli(ctx):
通过
#绑定命令和参数
def bind_func(名称、c、kwargs):
def func(**kwargs):
click.echo('我是'命令'。格式(名称))
如果不是kwargs:
打印('未找到kwargs')
返回(func)
#添加节点_数据中的所有键、值
对于键,kwargs.items()中的值:
if key.startswith(“”“”):
持续
如果键=='命令':
持续
#单击.echo('\t编辑选项:{}'。格式(键))
option=click.option('-{}.format(key,default=value))
func=选项(func)
#重命名命令并返回它
函数名
返回函数
def main():
'''
'''
#加载蜂窝对象(节点树)
hcmb=hcm.Honeycomb(数据路径)
#获取可构建的节点
nodes=hcmb.builder.get_buildable_nodes()
#确定根路径
cli_组={'| cli':cli}
对于节点中的节点:
nice\u name=node.get\u name()[1:]
路径=节点。获取路径()
cli_路径=“| cli”+路径
parent=node.get_parent()
如果不是家长:
父目录路径='cli'
其他:
parent_cli_path='| cli'+parent.get_path()
#获取节点数据以添加参数:
resolver\u dict=node.get\u resolver\u dict()
#在相应的父组中创建新组
func=bind_func(很好的名称,''u f',解析器'u dict)
新建组=客户端组[父客户端路径].group(name=nice\u name)(func)
#并将其附加到组列表中
cli\u组[cli\u路径]=新的\u组
#现在调用cli
cli()
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

抱歉,代码太长了,但是我想如果没有它,我很难理解我在做什么。也许我正试图强迫单击以其不希望的方式工作?

我已经成功地在fast中完成了类似的操作。然而,它是通过创建一个新的装饰器来包含我的所有选项,比如下面的
common\u选项

导入单击
_全局_选项=[
单击.option('-v','-verbose',count=True,default=0,help='verbose output'。),
click.option('-n','-dry-run',is_flag=True,default=False,help='dry-run mode')
]
def公用_选项(func):
对于反向中的选项(“全局选项”):
func=选项(func)
返回函数
然后,我会在创建组时将
@common_options
作为装饰器应用到组中,但我现在刚刚尝试过,装饰器只是函数包装器,其工作方式如下:

#将其用作装饰器的标准方式
@单击。组()
@共同选择
def cli():
通过
#将其用作函数
@单击。组()
def cli():
通过
通用_选项(cli)

感谢您的回复!我更改了标题并添加了一些细节。这真的很有帮助。我正在慢慢地把这一切拼凑起来。我的问题是,我不知道提前选择。它们是蜂巢的一部分。节点对象,是其他节点树中的子节点。。。任何想法都是有帮助的
honeycomb content
honeycomb content asset
content = {'studio_root': some_value}
    asset = {'studio_root': some_value (inherited), 'asset_name': lulu}