You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中自动构建CLI工具的调用类?

动态构建CLI链式调用方案

核心思路

利用Python的__getattr__动态属性创建和__call__实例调用特性,递归构建插件层级结构,实现类似命令行补全的链式调用体验,自动拼接命令并执行或返回命令列表。

实现代码

基础CLI命令类

import subprocess

class CLICommand:
    def __init__(self, parent_command=None):
        # 存储当前已拼接的命令片段,初始为根命令(如['command.exe'])
        self._command = parent_command.copy() if parent_command else []
    
    def __getattr__(self, name):
        # 动态生成子插件/子命令实例
        new_command = self._command + [name]
        sub_cmd = CLICommand(new_command)
        # 缓存属性,避免重复创建
        setattr(self, name, sub_cmd)
        return sub_cmd
    
    def __call__(self, *args, **kwargs):
        # 拼接最终命令:基础命令 + 位置参数 + 关键字参数(转成flag格式)
        final_command = self._command.copy()
        final_command.extend(args)
        
        for flag, value in kwargs.items():
            final_command.append(f"-{flag}")
            final_command.append(str(value))
        
        # 执行命令并返回结果,若仅需命令列表直接return final_command
        exec_result = subprocess.run(
            final_command,
            capture_output=True,
            text=True,
            check=False  # 不主动抛出异常,由测试环境处理返回码
        )
        
        return {
            'full_command': final_command,
            'stdout': exec_result.stdout,
            'stderr': exec_result.stderr,
            'return_code': exec_result.returncode
        }

初始化与调用示例

# 初始化根CLI,传入你的基础命令
cli = CLICommand(['command.exe'])

# 链式调用生成并执行命令
# 对应终端命令:command.exe plugin subplugin subsubplugin arg1 arg2 -a flaga -b flagb
test_result = cli.plugin.subplugin.subsubplugin('arg1', 'arg2', a='flaga', b='flagb')

# 查看结果
print(test_result['full_command'])
print(test_result['stdout'])

基于现有命令字典预加载结构(支持IDE补全)

如果需要从你的commands字典预加载所有插件层级,让IDE能识别属性(实现类命令补全),可以添加递归加载函数:

def preload_commands(cli_instance, cmd_dict):
    def _recursive_load(parent, current_level):
        for key, content in current_level.items():
            # 触发属性创建并缓存
            sub_cmd = getattr(parent, key)
            if isinstance(content, dict):
                # 递归加载子层级
                _recursive_load(sub_cmd, content)
    
    _recursive_load(cli_instance, cmd_dict)

# 你的现有命令字典示例
your_commands = {
    "plugin": {
        "subplugin": {
            "subsubplugin": ['-a', 'flaga', '-b', 'flagb']
        }
    }
}

# 预加载后,IDE输入cli.plugin.时会提示subplugin
preload_commands(cli, your_commands)

关键特性说明

  • 动态属性创建:通过__getattr__自动生成未定义的插件/子插件属性,无需手动编写每个命令的函数。
  • 灵活参数处理:支持位置参数和关键字参数(自动转成-flag value格式),适配不同CLI参数需求。
  • 可扩展性:无论是执行命令返回结果,还是仅返回命令列表注入现有测试架构,只需修改__call__方法的返回逻辑即可。

内容的提问来源于stack exchange,提问作者Shahaf Edri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:00:52