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

Python argparse互斥选项配置:添加stdin支持技术问询

解决argparse支持stdin输入的互斥选项问题

我明白你遇到的问题了——argparse的互斥组默认要求必须选择其中一个选项,但stdin输入是没有对应命令行参数的,所以直接用互斥组会导致管道输入时触发错误。下面是一个完整的解决方案,既能实现你要的三个互斥输入方式和两个互斥输出方式,又能优雅处理stdin场景:

完整代码示例

import argparse
import sys
import json

def main():
    # 创建解析器
    parser = argparse.ArgumentParser(description='Process JSON input and output with multiple input/output options.')
    
    # 输入互斥组:-i 文件 / 位置参数JSON字符串(可选)
    input_group = parser.add_mutually_exclusive_group()
    input_group.add_argument('-i', '--input', help='Path to input JSON file')
    # nargs='?' 让位置参数变为可选,这样互斥组允许没有选中任何选项(留给stdin处理)
    input_group.add_argument('json_str', nargs='?', help='Direct JSON string input')
    
    # 输出互斥组:-o 文件 / 默认stdout
    output_group = parser.add_mutually_exclusive_group()
    output_group.add_argument('-o', '--output', help='Path to output JSON file (default: print to stdout)')
    
    args = parser.parse_args()
    
    # 处理输入逻辑
    try:
        if args.input:
            # 从指定文件读取
            with open(args.input, 'r', encoding='utf-8') as f:
                data = json.load(f)
        elif args.json_str:
            # 从位置参数读取JSON字符串
            data = json.loads(args.json_str)
        else:
            # 尝试从stdin读取
            stdin_content = sys.stdin.read().strip()
            if not stdin_content:
                # 如果stdin为空且没有其他输入,抛出错误提示
                parser.error("No input provided! Use one of:\n"
                            "  -i <input-file>\n"
                            "  script.py '{\"key\": value}'\n"
                            "  echo '{\"key\": value}' | script.py")
            data = json.loads(stdin_content)
    except json.JSONDecodeError as e:
        parser.error(f"Invalid JSON format: {str(e)}")
    except FileNotFoundError:
        parser.error(f"Input file not found: {args.input}")
    
    # 处理输出逻辑
    try:
        if args.output:
            # 写入指定文件
            with open(args.output, 'w', encoding='utf-8') as f:
                json.dump(data, f, indent=2)
        else:
            # 输出到stdout
            print(json.dumps(data, indent=2))
    except IOError as e:
        parser.error(f"Output file error: {str(e)}")

if __name__ == "__main__":
    main()

关键细节解释

  1. 输入互斥组的处理:

    • 给位置参数json_str设置nargs='?',让它变为可选参数,这样互斥组允许没有选中任何选项(此时我们就可以转而读取stdin)。
    • 解析参数后,手动判断输入来源:先检查-i,再检查位置参数,最后尝试读取stdin。如果三者都为空,用parser.error()给出清晰的错误提示。
  2. stdin的检测:

    • 通过sys.stdin.read().strip()读取stdin内容,判断是否为空。如果用户直接运行脚本而没有管道输入,stdin会是空的,这时候触发错误提示。
  3. 错误处理增强:

    • 捕获JSONDecodeError,提示用户输入的JSON格式无效。
    • 捕获FileNotFoundError,提示输入文件不存在。
    • 捕获IOError,处理输出文件的读写错误。

测试所有场景

你可以用以下命令测试各个功能:

  • 从文件输入,输出到stdout:
    python script.py -i input.json
    
  • 直接传入JSON字符串,输出到文件:
    python script.py '{"a": 1, "b": "test"}' -o output.json
    
  • 从stdin读取输入,输出到stdout:
    echo '{"name": "Alice", "age": 30}' | python script.py
    
  • 从stdin读取文件内容,输出到文件:
    cat input.json | python script.py -o output.json
    

内容的提问来源于stack exchange,提问作者leonard vertighel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:09:04