【问题标题】:How to skip a positional argument in Python Argparse如何在 Python Argparse 中跳过位置参数
【发布时间】:2016-02-02 12:06:50
【问题描述】:

我使用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 filename 时它不起作用,因为它需要counter

所以我尝试将所有内容插入到这样的单个参数中:

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

但它不起作用,因为它运行 counter 而不是 fasta2bed...

我怎样才能做到这一点?

【问题讨论】:

标签: python arguments argparse


【解决方案1】:

据我所知,您不能以您想要的方式跳过争论。也就是说,您似乎并不想跳过一个。做到这一点的方法是改变你看待问题的方式。可行的是有一个接受“counter”或“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

【讨论】:

  • @chepner - 啊,是的,复制和粘贴太快了……现在修复了。谢谢!
  • 非常感谢!以及如何分配两个不同的功能来对抗 e fasta2bed?我尝试使用 if 语句,但它不起作用并且总是运行计数器而不是 fastabed :(
  • @Revo:你走对了。检查我在答案中添加的内容。
  • 太好了,现在效果很好!我的最后一个问题是:我可以(以这种方式)添加帮助来解释 counter 和 fasta2bed(以及我将添加的其他工具)的作用吗?非常感谢 GreenMatt :)
  • @Revo:据我所知,使用消息(您在实例化解析器时定义的)或参数的帮助消息的长度没有限制。所以——尽管它可能很长——你可以使用这些工具来做你想做的事。我有一个应用程序,如果打印硬拷贝,它的使用消息将超过 8.5" x 11"(或 A4)页面。
【解决方案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。在迷失测试特定值之前,您需要清楚地了解生成的命名空间是什么样的。如果用户两个都没有选择会发生什么?

其他人可能会建议使用子解析器。我认为这是一个经常引起更多混乱的高级工具。

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

【讨论】:

  • 非常感谢!以及如何分配两个不同的功能来对抗 e fasta2bed?我尝试使用 if 语句,但它不起作用并且总是运行计数器:(
【解决方案3】:

它可以使用类似的东西工作吗:

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

【讨论】:

  • 但是通过第二种方式,我可以获得像 argparse 那样的帮助页面吗?非常感谢!
猜你喜欢
  • 2016-01-08
  • 1970-01-01
  • 2011-05-27
  • 2012-01-29
  • 2011-07-19
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 2011-05-27
相关资源
最近更新 更多