如何在Python Argparse中跳过位置参数

时间:2015-11-02 14:55:48

标签: python arguments argparse

大家好我是编程和Python的新手。我寻找了我的问题的答案,但我找不到它。

我使用Argparse来解析脚本的参数。现在我想编写一个程序,如果第一个参数(在程序名之后)是工具的名称(在类中关闭),则运行特定工具。例如,如果我想运行“计数器”工具,我必须输入:

python myscript.py counter filename

如果我想运行“fasta2bed”,我必须输入:

python myscript.py fasta2bed filename

我编写了这段代码,但似乎你不能跳过Argparse的位置参数:

import argparse

parser=argparse.ArgumentParser(
    usage="""python myscript.py {toolname} filename [-option]""",
    description='''Description.''',
    epilog="""Epilog.""")
parser.add_argument('counter', nargs='?', choices=['counter'],        help='count how many features are in the input file [-l][-s]')
parser.add_argument('fasta2bed', nargs='?', choices=['fasta2bed'],    help='read sequences in FASTA format and print out BED format')
parser.add_argument('filename', help='the input file name')
parser.add_argument('-l', '--long', action='store_true', help='retrive a    long summary file (default)')
parser.add_argument('-s', '--short', action='store_true', help='retrive a    short summary file')
args=parser.parse_args()

问题是,当我尝试运行python myscript.py fasta2bed文件名时,它不起作用,因为它需要计数器。

所以我尝试在一个参数中插入所有这些:

parser.add_argument('tool', nargs='?', choices=['counter', 'fasta2bed'], help='help')

有了这个目标:

data = open("inputfile", "r")

if args.tool == "counter":
    counter(data).summarize()      #summarize is a function present in the counter class
elif args.tool == "fasta2bed":
    fasta2bed(data)                #fasta2bed is just a function

但它不起作用,因为它运行计数器而不是fasta2bed ......

有没有办法达到这个目标?也许没有argparse?

非常感谢你的时间!

3 个答案:

答案 0 :(得分:2)

使用此行的脚本副本

parser.add_argument('tool', choices=['counter', 'fasta2bed'], help='help')

print(args)

我得到了理想的行为

0827:~/mypy$ python stack33480471.py counter filename
Namespace(filename='filename', long=False, short=False, tool='counter')
0828:~/mypy$ python stack33480471.py fasta2bed filename
Namespace(filename='filename', long=False, short=False, tool='fasta2bed')
0828:~/mypy$ python stack33480471.py tool filename
usage: python myscript.py {toolname} filename [-option]
stack33480471.py: error: argument tool: invalid choice: 'tool' (choose from 'counter', 'fasta2bed')

请注意,我放弃了nargs='?'。解析更清晰,更可预测。我只是展示args。在丢失测试特定值之前,您需要清楚地了解生成的命名空间是什么样的。如果用户既没有选择会怎么样?

其他人可能会建议使用subparser。我认为这是一种经常引起更多混淆的高级工具。

使用store_true选项也是一个好主意。但它需要使用'--counter'而不是'counter'。这不错,只是不同。

答案 1 :(得分:2)

据我所知,你不能以你想要的方式跳过论证。也就是说,你似乎并不想跳过一个。这样做的方法是改变你对问题的看法。什么是有效的是让一个论点接受“反击”和“反击”。或者' fasta2bed'。更改代码中的相关行可能会产生类似:

import argparse
parser=argparse.ArgumentParser(
    usage="""python myscript.py {toolname} filename [-option]""",
    description='''Description.''',
    epilog="""Epilog.""")
parser.add_argument('toolname', choices=['counter', 'fasta2bed'], help='the name of the tool to be used')
parser.add_argument('filename', help='the input file name')
parser.add_argument('-l', '--long', action='store_true',     help='retrive a long summary file (default)')
parser.add_argument('-s', '--short', action='store_true', help='retrive a short summary file')
args=parser.parse_args()

希望这有助于您入门。

修改其他资料:

您可以通过检查args.toolname:

来检查工具名的选项
if args.toolname == 'counter':
    print 'Running counter'
else:
    print 'Running fasta2bed'

请注意,如果您有2个以上的选择,则需要使用elif

答案 2 :(得分:0)

它可以使用类似的东西吗?

parser.add_argument('--counter', action='store_true', default=False)
parser.add_argument('--fasta2bed', action='store_true', default=False)

另外要在python中检查脚本后的直接参数,可以使用:

import sys

filename, methodname = sys.argv

现在您将第一个参数传递到脚本methodname