在互斥参数组中使用stdin

时间:2018-04-07 09:34:49

标签: python python-2.7 argparse

我正在尝试在脚本中使用argparse,以便我可以将字符串作为参数或通过标准输入传递。我想我可以使用add_mutually_exclusive_group,并设置required=True来强制只需要一个参数。所以,我创建了以下脚本(my_script.py):     

#!/usr/bin/env python

import argparse
from sys import stdin

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('str_arg', nargs='?', type=str)
group.add_argument('str_in', nargs='?', type=argparse.FileType('r'), default=stdin)
args = parser.parse_args()
print args.str_arg or args.str_in.readline()

将字符串作为参数传递可以正常工作。但是,当我尝试从标准输入中管道字符串时,如下所示:

$ echo Hello | python my_script.py

Python抱怨one of the arguments str_arg str_in is required。我究竟做错了什么?有没有更好的方法来实现这一目标?

3 个答案:

答案 0 :(得分:2)

看起来您应该尝试使用花哨的argparse功能,只是一些简单的逻辑:

import argparse
from sys import stdin

parser = argparse.ArgumentParser()
parser.add_argument('str_arg', nargs='?', type=str)
args = parser.parse_args()
print(args.str_arg or stdin.readline())

答案 1 :(得分:1)

互斥组中的2个位置不起作用。

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('str_arg', nargs='?')
group.add_argument('str_in', nargs='?')
args = parser.parse_args()
print(args)

样本运行:

0217:~/mypy$ python3 stack49705916.py 
usage: stack49705916.py [-h] (str_arg | str_in)
stack49705916.py: error: one of the arguments str_arg str_in is required

0904:~/mypy$ python3 stack49705916.py foo
Namespace(str_arg='foo', str_in=None)

0904:~/mypy$ python3 stack49705916.py foo bar
usage: stack49705916.py [-h] (str_arg | str_in)
stack49705916.py: error: argument str_in: not allowed with argument str_arg

管道不能替代命令行参数。 stdin必须单独阅读。

import argparse, sys
print(sys.argv)
parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('str_arg', nargs='?')
group.add_argument('str_in', nargs='?')
args = parser.parse_args()
print(args)
print(sys.stdin.read())

0909:~/mypy$ echo 'hello' | python3 stack49705916.py foo
['stack49705916.py', 'foo']
Namespace(str_arg='foo', str_in=None)
hello

argparse.FileType('r')-视为stdin

print(sys.argv)
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--str_in', type=argparse.FileType('r'))
args = parser.parse_args()
print(args)
print(args.str_in.read())

运行

0945:~/mypy$ python3 stack49705916.py -i test.txt
['stack49705916.py', '-i', 'test.txt']
Namespace(str_in=<_io.TextIOWrapper name='test.txt' mode='r' encoding='UTF-8'>)
2000+0
2001+2
2002+1

0946:~/mypy$ python3 stack49705916.py -i -
['stack49705916.py', '-i', '-']
Namespace(str_in=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>)
typing hello on input line

typing hello on input line


0947:~/mypy$ echo Hello | python3 stack49705916.py -i -
['stack49705916.py', '-i', '-']
Namespace(str_in=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>)
Hello

0947:~/mypy$ 

答案 2 :(得分:0)

在shell中,您可以使用引号而不是管道将echo Whatever的输出作为参数传递:

$ python my_script.py `echo whatever`