我正在尝试创建一个argparse可选参数,该参数可能-OR-可能没有关联的输入值。我想要以下行为:
1.未指定参数,值= None
2.参数指定了一个值,值= user_input
3.指定的参数不带值,value =源自位置值
前两个很简单。这是我不知道的第三个。我发现2篇类似的文章:
python argparse optional positional argument with detectable switch
对于没有值的可选参数,此值将默认值设置为常量。
Argparse optional positional arguments?
这个主题很接近,但不是我所需要的(他从系统调用中获取默认值):
我希望根据位置值确定我的位置。
我创建的简单示例代码:
parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')
设置输入并打印时:
args = parser.parse_args('my.h5 -c my_file.csv --pnf'.split())
print ('Input = %s' % args.input)
print ('CSV file = %s' % args.csv)
print ('PNF file = %s' % args.pnf)
我得到:
Input = my.h5
CSV file = my_file.csv
PNF file = None
如果我将输入修改为:
args = parser.parse_args('my.h5 -c'.split())
结果输出为:
Input = my.h5
CSV file = None
PNF file = None
当Value = None
时,我无法判断可选参数是否未定义,或者是否已定义但没有值。在第二种情况下,我想从位置参数派生CSV文件名(在此示例中,派生名称为my.csv
)。当定义--pnf时,我想做同样的事情(默认情况下,以上的默认PNF为my.pnf
)。有办法吗?
答案 0 :(得分:2)
我无法判断可选参数是否未定义,或者是否已定义但没有值
如果您创建解析器like this:
parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
现在可以区分这三种情况。
-c val
,它将以值args
出现在"val"
中。 -c
是不带任何值的传递,它将在args
中以值None
出现。 -c
被完全省略,则它不会出现在args
中。 -p
也是如此。
答案 1 :(得分:0)
使用const
参数:
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?', const='foobar')
parser.add_argument('-p', '--pnf', nargs='?', const='foobar')
args = parser.parse_args()
print(args)
if args.csv and args.csv=='foobar':
args.csv = args.input
args.pnf = args.input if (args.pnf and args.pnf=='foobar') else args.pnf
print(args)
您的两个示例输入:
0933:~/mypy$ python3 stack53228663.py my.h5 -c my_file.csv --pnf
Namespace(csv='my_file.csv', input='my.h5', pnf='foobar')
Namespace(csv='my_file.csv', input='my.h5', pnf='my.h5')
0933:~/mypy$ python3 stack53228663.py my.h5 -c
Namespace(csv='foobar', input='my.h5', pnf=None)
Namespace(csv='my.h5', input='my.h5', pnf=None)
答案 2 :(得分:0)
为了完整性(和将来参考),我将发布使用argument_default=argparse.SUPPRESS
时获取参数所需的修改代码。见下文:
parser = argparse.ArgumentParser(argument_default=argparse.SUPPRESS)
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?')
parser.add_argument('-p', '--pnf', nargs='?')
args = parser.parse_args('my.h5 -c my_file --pnf'.split())
for d_key, d_val in vars(args).items() :
print (d_key, d_val)
输出结果:
input my.h5
csv my_file
pnf None
对于第二组输入
args = parser.parse_args('my.h5 -c'.split())
print(vars(args))
for d_key, d_val in vars(args).items() :
print (d_key, d_val)
输出看起来像这样:
input my.h5
csv None
答案 3 :(得分:0)
根据@hpaulj的早期评论,这显示了我使用default=False, const=True
实现的逻辑。
parser = argparse.ArgumentParser()
parser.add_argument('input')
parser.add_argument('-c', '--csv', nargs='?', default=False, const=True)
parser.add_argument('-p', '--pnf', nargs='?', default=False, const=True)
args = parser.parse_args('my.h5 -c'.split())
print(vars(args))
HDF5_FILE = args.input
if isinstance(args.csv, str) :
CSV_FILE = args.csv
elif args.csv :
CSV_FILE=HDF5_FILE[:-3] + '_v3_stress.csv'
else :
CSV_FILE = ''
# repeat above logic for args.pnf
print ('input=', HDF5_FILE, ', csv=', CSV_FILE, ' pnf=', PNF_FILE )
结果输出如下:
{'input': 'my.h5', 'csv': True, 'pnf': False}
hdf5= my.h5 , csv= my_v3_stress.csv pnf=
修改后的'parse_args()'和结果输出:
args = parser.parse_args('my.h5 -c my_file.csv -p'.split())
礼物:
{'input': 'my.h5', 'csv': 'my_file.csv', 'pnf': True}
hdf5= my.h5 , csv= my_file.csv pnf= my_v3_stress.nrf
如果要检查的变量很多,可以将if/elif/else
逻辑移至返回所需值的def
。