如何判断optparse选项是在命令行中传递的还是作为默认值的

8 投票
3 回答
7506 浏览
提问于 2025-04-15 21:20

使用python的optparse.py,有没有办法判断一个特定的选项值是从命令行设置的,还是用的默认值。

理想情况下,我希望能有一个字典,内容和默认值一样,但里面是实际从命令行提供的选项。

我知道可以把每个选项的值和默认值进行比较,但这样并不能区分出一个值是通过命令行传入的,还是正好和默认值相同。

谢谢!


编辑

抱歉,我最开始的表述不太清楚。

我有很多脚本是通过批处理文件调用的。为了审计的需要,我想记录下传入的选项,以及它们是从命令行、默认值还是其他方式传入的,记录到一个日志文件里。

通过默认值可以判断一个选项是否与默认值匹配,但这仍然不能告诉你这个值是否确实是从命令行传入的。这点很重要:如果一个选项是从命令行传入的,并且和默认值一致,那么如果你在代码中更改了默认值,脚本仍然会得到相同的值。

对我来说,拥有一个类似于默认值的东西,里面包含实际提供的值,感觉是很自然的。

为了让问题更具体,在这个例子中:

>>> 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的一些东西)

再次感谢!

3 个回答

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类里,那就太好了。

3

不知道你的代码是什么样的,没法给出更好的答案,不过……

  1. 简单来说,不要把默认值传给解析器,然后检查一下是否是 None 值。None 值在 optparse 库中是一个默认值,所以你可以拿到你自己的默认值,然后像往常一样处理;

  2. 扩展 optparse 来让它更符合你的需求。

我不知道你的程序具体是什么样的,但通常来说,当配置一样的时候,改变行为并不是一个好的设计。

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))

撰写回答