8

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

理想情况下,我希望有一个 dict 就像默认值一样,但包含从命令行实际提供的选项

我知道您可以将每个选项的值与默认值进行比较,但这无法区分通过与默认值匹配的命令行传递的值。

谢谢!


编辑

对不起,我原来的措辞不是很清楚。

我有大量从批处理文件调用的脚本。出于审计目的,我想报告正在传递的选项,以及它们是否从命令行、默认或其他方式传递到日志文件。

使用默认值可以判断选项是否与默认值匹配,但这仍然不能告诉您它是否实际上是从命令行提供的。这可能是相关的:如果一个选项是从命令行传递的并且与默认值一致,如果您随后更改代码中的默认值,则脚本仍将获得相同的值。

对我来说,拥有一个等同于默认值的东西,包含实际提供的值会感觉很自然。

为了使问题具体化,在此示例中:

>>> 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 上遗漏了一些东西)

再次感谢

4

3 回答 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))
于 2012-07-02T17:55:45.433 回答
3

不知道你的代码不可能给出更好的答案,但是......

  1. 只是不要将默认值传递给解析器并检查None值。值Noneoptparselib 的默认值,因此您可以检索自己的默认值并照常行事;

  2. 延伸optparse到专门化它。

我不知道你的程序,但是当配置相同时,通常它不是一个好的设计更改行为。

于 2010-04-07T14:54:23.663 回答
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 类中,那就太好了。

于 2014-05-02T17:37:56.703 回答