Python argparse是互斥的,stdin是选项之一

Python argparse是互斥的,stdin是选项之一,python,json,python-3.x,stdin,argparse,Python,Json,Python 3.x,Stdin,Argparse,我希望我的脚本接收这些相互排斥的输入选项: 包含JSON script.py-i input.JSON的输入文件; 包含JSON脚本的字符串。py'{a:1}'; 来自stdin echo{a:1}| script.py或cat input.JSON | script.py的JSON。 这些相互排斥的输出选项: 包含JSON的输出文件; 标准输出中的JSON。 所以我试着用这个代码 import json,sys,argparse parser = argparse.ArgumentParser

我希望我的脚本接收这些相互排斥的输入选项:

包含JSON script.py-i input.JSON的输入文件; 包含JSON脚本的字符串。py'{a:1}'; 来自stdin echo{a:1}| script.py或cat input.JSON | script.py的JSON。 这些相互排斥的输出选项:

包含JSON的输出文件; 标准输出中的JSON。 所以我试着用这个代码

import json,sys,argparse
parser = argparse.ArgumentParser(description='Template for python script managing JSON as input/output format')

group = parser.add_mutually_exclusive_group()
group.add_argument('--input-file', '-i',  type=str, help='Input file name containing a valid JSON.', default=sys.stdin)
group.add_argument('json',    nargs='?',  type=str, help='Input string containing a valid JSON.' , default=sys.stdin)
parser.add_argument('--output-file', '-o',type=str, help='Output file name.')

args = parser.parse_args()

if not sys.stdin.isatty():
    data = sys.stdin.read()
else:
#    args = parser.parse_args()
    if args.input_file :
        data=open(args.input_file).read()
    elif args.json :
        data=args.json


datain=json.loads(data)

dataout=json.dumps(datain, indent=2)

if args.output_file :
        output_file=open(args.output_file, 'w')
        output_file.write(dataout+'\n')
        output_file.close()
else:
    print (dataout)
但它不适用于stdin,因为它至少需要两个组选项中的一个

如何在输入选项列表中添加标准输入

如果我这样调用它,添加default=sys.stdin参数是有效的

echo '{}' | ./script.py -
但不是这样的:

echo '{}' | ./script.py
我将利用默认值为sys.stdin的argparse.FileType

我将利用默认值为sys.stdin的argparse.FileType

与:

你可以测试一下

if args.input_file is None:
   <-i wasn't supplied>
else:
    if args.input_file == '-':
        f = sys.stdin
    else:
        f = open(args.input_file)
    data = f.read()  # etc
stdin的一个棘手问题是,您不希望在使用后像使用常规文件名一样关闭它。而且你不能用它来形容一个人

与stdout类似

有些代码在打开文件时设置一个标志,而不是接收一个已经打开的文件,因此它可以记住在最后关闭文件

group.add_argument('--input-file','-i',nargs='?', default=None, const=sys.stdin)
将arg.input_文件设置为stdin(在没有参数的情况下给定-i)。但我认为寻找纯字符串是一个更好的主意。

使用:

你可以测试一下

if args.input_file is None:
   <-i wasn't supplied>
else:
    if args.input_file == '-':
        f = sys.stdin
    else:
        f = open(args.input_file)
    data = f.read()  # etc
stdin的一个棘手问题是,您不希望在使用后像使用常规文件名一样关闭它。而且你不能用它来形容一个人

与stdout类似

有些代码在打开文件时设置一个标志,而不是接收一个已经打开的文件,因此它可以记住在最后关闭文件

group.add_argument('--input-file','-i',nargs='?', default=None, const=sys.stdin)

将arg.input_文件设置为stdin(在没有参数的情况下给定-i)。但我认为找一根普通的绳子是个更好的主意。

太好了!但是使用这段代码时,stdin为空且没有参数。\script.py会导致无限期等待,而我认为至少需要一个方法stdin、string或file。那么,一种类型如何输入到程序中?从stdin读取意味着在输入未重定向时从控制台读取。很抱歉使用了错误的术语:我的意思是输入来自管道,例如echo{}script.py或cat input.json | script.py.Right。这是使用stdin的一种方法。但同样有效的方法是在程序运行时键入。如果您通过在控制台上键入来故意排除在程序中输入文本的功能,这将使您的用户感到困惑。没错,它正在等待下一行文本。毕竟,您的数据可能比一行长。输入完数据后,按操作系统使用的文件结束键序列指示文件结束。如果您在UNIX或Linux上,这可能是Control-D。如果您在Windows上,这可能是Control-Z。太棒了!但是使用这段代码时,stdin为空且没有参数。\script.py会导致无限期等待,而我认为至少需要一个方法stdin、string或file。那么,一种类型如何输入到程序中?从stdin读取意味着在输入未重定向时从控制台读取。很抱歉使用了错误的术语:我的意思是输入来自管道,例如echo{}script.py或cat input.json | script.py.Right。这是使用stdin的一种方法。但同样有效的方法是在程序运行时键入。如果您通过在控制台上键入来故意排除在程序中输入文本的功能,这将使您的用户感到困惑。没错,它正在等待下一行文本。毕竟,您的数据可能比一行长。输入完数据后,按操作系统使用的文件结束键序列指示文件结束。如果您在UNIX或Linux上,则可能是Control-D。如果您在Windows上,则可能是Control-Z。
group.add_argument('--input-file','-i',nargs='?', default=None, const=sys.stdin)