如何使用 nargs='+' 解析多个位置参数

pos*_*def 4 python parameter-passing argparse python-3.x

以下是我想要实现的目标的简短摘要:

  • 获取一个或多个(表格)文件
  • 查找特定的字符串键(目前只有一个键,但我可以想象将其扩展以接受多个键)
  • 与键匹配的行提取给定位置或位置范围处的字符。

因此,在理想的情况下,我希望通过以下方式运行我的脚本,它们都是有效的用例:

python myscript.py file1 file2 file3 "key" 10
python myscript.py file1 file2 "key" 10 12
python myscript.py file1 "key" 10 12
python myscript.py file1 "key" 10
Run Code Online (Sandbox Code Playgroud)

鉴于我尝试过的用例:

parser = argparse.ArgumentParser()
parser.add_argument("files", nargs='+', help="input files")
parser.add_argument("gene", help="gene of interest")
parser.add_argument("pos", nargs='+', type=int, help="position(s) to analyze")

""" Validate pos """
if len(args.pos) > 2:
    sys.exit("Positions argument needs to be a single integer or two integers denoting a range!")

...

# in some other function
if len(args.pos) == 1:
    key = row[SIND][args.pos[0]]
elif len(args.pos) == 2:
    key = row[SIND][args.pos[0] : args.pos[1]]
else:
    print(args.pos, len(args.pos))
    sys.exit("args.pos assertion failed!")
Run Code Online (Sandbox Code Playgroud)

当只有一个整数时它有效,但当我发送两个整数来分析范围时则无效。在后一种情况下,“密钥”也被解释为文件,因此我得到了FileNotFoundError: [Errno 2] No such file or directory: 'IGHV4-39'.

问题1:是否可以标记或指示位置参数,以便我可以告诉 argparsefiles参数何时结束和gene开始?我不想让它们成为可选参数,因为如果省略三个参数中的任何一个,脚本的逻辑就不完整。

问题2:将pos参数分成两部分是否有其他帮助?pos 接受一个整数,range 接受两个整数,然后以某种方式使它们互斥?

有任何想法吗?

dap*_*azz 5

问题 1 的回答

“是否可以标记……位置参数?” 好吧,如果你这样做了,那么它们就不再是立场争论了!因为毕竟位置参数是通过处于位置来定义的,而不是通过被标记来定义的。

我认为你真正需要的是required选择,而不是尝试使用位置参数太聪明。您的目标是创建一个非常聪明的界面,无论输入如何,都能神奇地计算出您想要的内容,或者创建一个可预测地工作并产生良好错误消息的界面?

我可以对这一点进行讽刺,因为我过去花了太多时间做第一个而不是只做第二个。

那么为什么不这样呢:

测试.py

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--files', required=True, nargs='+')
parser.add_argument('--genes', required=True, nargs='+')
parser.add_argument(
    '--pos', required=True, nargs='+', type=int, help="position(s) to analyze")

opts = parser.parse_args()
print(dir(parser))

print('files: %s, genes: %s, poses: %s' % (
    opts.files, opts.genes, opts.pos))
Run Code Online (Sandbox Code Playgroud)

所以:

$ python test.py
usage: test.py [-h] --files FILES [FILES ...] --genes GENES [GENES ...] --pos
           POS [POS ...]
test.py: error: the following arguments are required: --files, --genes, --pos

$ python test.py --files file1 file2 --genes xzy --pos 2 1
files: ['file1', 'file2'], genes: ['xzy'], poses: [2, 1]
Run Code Online (Sandbox Code Playgroud)

回答问题 2

您本质上不是在问“这里最好的界面是什么”吗?当然,这是你需要决定的事情。我的建议:保持简单。为什么不这样做:

parser.add_argument('--start', '-s', required=True, nargs=1, type=int)
parser.add_argument('--end', '-e', nargs=1, type=int)

opts = parser.parse_args()
if opts.end is None:
    opts.end = opts.start + 1
Run Code Online (Sandbox Code Playgroud)