有没有办法说服Python的getopt处理选项的可选参数?

8
根据Python的 getopt 文档(我想是这个),选项字段应该像 getopt()函数一样运作。然而,我似乎无法为我的代码启用可选参数:
#!/usr/bin/python
import sys,getopt

if __name__ == "__main__":
    try:
        opts, args = getopt.gnu_getopt(sys.argv[1:], "v::", ["verbose="])
    except getopt.GetoptError, err:
        print str(err)
        sys.exit(1)

    for o,a in opts:
        if o in ("-v", "--verbose"):
            if a:
                verbose=int(a)
            else:
                verbose=1
            print "verbosity is %d" % (verbose)

结果为:

$ ./testopt.py -v
option -v requires argument
$ ./testopt.py -v 1
verbosity is 1
5个回答

11

getopt不支持可选参数。对于长选项,你可以这样做:

$ ./testopt.py --verbose=

这会导致空字符串值。

您可以发现argparse模块更加灵活。


6
很遗憾,没有办法。根据 optparse文档: 通常,一个选项要么带有参数,要么不带。许多人想要一个“可选选项参数”功能,这意味着如果某些选项看到了它,它们将带有一个参数,否则就没有参数。这在解析上存在一定争议:如果“-a”带有可选参数且“-b”是完全不同的选项,我们如何解释“-ab”?由于存在这种歧义,optparse 不支持此功能。编辑:糟糕,这是针对 optparse 模块而不是 getopt 模块,但两个模块都没有“可选选项参数”的原因相同。

是的,我刚刚注意到了,典型的“错误标签”综合症。 然而,我仍然认为这种推理对于 getopt 也是相对的。 - Isaiah
此外,长选项可以明确地具有可选参数;"--foo" vs. "--foo=arg"。Python似乎不支持这一点,这非常糟糕;这是从头开始重新实现某些东西的症状... - Glenn Maynard
@Glenn:Python 支持一切,但 optparse 的维护者不支持。请看我的回答,有一个不错的模块。 - SilentGhost
我曾经阅读过optparse文档,了解为什么它们不支持该功能,但对于opt而言并不清楚。这很遗憾,因为“-v”或“-v 2”是一个相当有用的习语,Perl和C都没有问题。 - stsquad

3
您可以像这样使用 getopt 来设置可选参数:
import getopt
import sys

longopts, shortopts = getopt.getopt(sys.argv[1:], shortopts='', longopts=['env='])
argDict = dict(longopts)

if argDict.has_key('--env') and argDict['--env'] == 'prod':
    print "production"
else:
    print "sandbox"

使用方法:

$ python scratch.py --env=prod
production

$ python scratch.py --env=dev
sandbox

$ python scratch.py
sandbox

1
除非你的示例中没有使用可选参数:如果没有相应的参数,--env 仍然可以工作吗? - Alexej Magura

0

Python的getopt应该真正支持可选参数,就像GNU getopt一样,需要在指定参数时使用'='。现在你可以通过隐式地将--option更改为--option=来轻松模拟它,只要遵循这个约束条件。

例如,您可以指定--option需要一个参数,然后按如下方式调整--option:--option=

for i, opt in enumerate(sys.argv):
    if opt == '--option':
        sys.argv[i] = '--option='
    elif opt == '--':
        break

0
如果您使用的是2.3或更高版本,您可能想尝试使用optparse模块,因为它更加“方便、灵活和强大...”,而且更新。不过,正如Pynt所回答的那样,似乎无法完全得到您想要的结果。

除了 optparser 文档外,45分钟前 Pynt 发布了其他的内容! - SilentGhost
@SilentGhost:在阅读Pynt的答案时,我没有看到任何建议使用optparse而不是get_opt,这正是我想表达的。诚然,我最初没有解释清楚,但现在已经编辑过了。 - PTBNL
optparse明确表示不支持对选项的可选参数。 - stsquad
@stsquad:是的,我在(编辑后的)答案中注意到了。我的观点是,如果你要这样做,你可能想考虑使用optparse而不是get_opt。 - PTBNL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接