如何知道optparse选项是在命令行中传递还是作为默认值。

8
使用python optparse.py,有没有一种方法可以确定特定选项值是从命令行还是默认值设置的。理想情况下,我希望有一个字典,就像defaults一样,但包含实际从命令行提供的选项。我知道你可以将每个选项的值与defaults进行比较,但这不能区分通过命令行传递匹配默认值的值。谢谢!抱歉我的原始措辞不太清楚。我有很多从批处理文件调用的脚本。出于审计目的,我想报告传递的选项以及它们是从命令行、默认还是其他方式传递到日志文件中。使用defaults,您可以确定选项是否与默认值匹配,但这仍然无法告诉您它是否实际上是从命令行提供的。这可能是相关的:如果选项从命令行传递并与默认值相符,如果您随后在代码中更改默认值,则脚本仍将获得相同的值。对我来说,拥有与defaults等效的内容(包含实际提供的值)会感觉非常自然。为了使问题具体化,在此示例中:
>>> sys.argv = ['myscript.py','-a','xxx']
>>> import optparse
>>> parser = optparse.OptionParser()
>>> parser.add_option('-a', default = 'xxx')
>>> parser.add_option('-b', default = 'yyy')

我该如何知道选项 a 是从命令行传递的?是手动解析命令行的唯一方法吗?

(我知道这只是一个相对较小的问题,但我认为询问一下还是有必要的,以防我在 optparse 上漏掉了什么细节)

再次感谢


2
但是默认值的目的不就是让你不必担心传递了哪些选项,无论它们是否与默认值匹配吗? - Raphaël Saint-Pierre
也许这意味着你需要另一个选项? - codeape
请看我的编辑,这是关于审计的,所以脚本被调用的方式确实很重要。 - user265454
3个回答

8

以下是常规代码:

opts, args = parser.parse_args()

如果您使用以下代码,将会有一个额外的值对象opts_no_defaults,其中包含用户明确指定的选项:
opts_no_defaults = optparse.Values()
__, args = parser.parse_args(values=opts_no_defaults)
opts = Values(parser.get_default_values().__dict__)
opts._update_careful(opts_no_defaults.__dict__)

最终,opts 应该与初始的样板代码相同。
print opts_no_defaults.__dict__
print opts.__dict__
for opt in parser._get_all_options():
    if opt.dest:
        print "Value of %s: %s" % (opt._long_opts[0], getattr(opts, opt.dest))
        print "Is %s specified by user? %s" % (opt._long_opts[0], hasattr(opt_no_defaults, opt.dest))

非常好!我正在考虑创建一个自定义的 OptionParser.get_default_values(),返回一个自定义的 Values 来跟踪值是否具有默认值。 - haridsv

3
不了解您的代码,很难给出更好的答案,但是...
1. 简单地不要将默认值传递给解析器,并检查None值。 None值是optparse库的默认值,因此您可以检索自己的默认值并像通常一样操作; 2. 扩展optparse以进行专门化。
我不知道您的程序,但通常在配置相同的情况下更改行为不是一个好的设计。

1
def is_opt_provided (parser, dest):
   if any (opt.dest == dest and (opt._long_opts[0] in sys.argv[1:] or opt._short_opts[0] in sys.argv[1:]) for opt in parser._get_all_options()):
      return True
   return False    

使用方法:

parser = OptionsParser()
parser.add_option('-o', '--opt', dest='opt_var', ...)

if is_opt_provided(parser, 'opt_var'):
   print "Option -o or --opt has been provided"

希望Python维护者将建议的函数包含到OptionParser类中,这样会很好。

这种方法极不可靠,因为即使选项字符串匹配参数中的某些内容,它也会返回假。 - haridsv

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