How to know if optparse option was passed in the command line or as a default

杀马特。学长 韩版系。学妹 提交于 2019-12-23 07:58:26

问题


Using python optparse.py, is there a way to work out whether a specific option value was set from the command line or from the default value.

Ideally I would like to have a dict just like defaults, but containing the options actually supplied from command line

I know that you could compare the value for each option with defaults, but this wouldn't distinguish a value was passed through command line which matched the default.

Thanks!


EDIT

Sorry my original phrasing wasn't very clear.

I have a large number of scripts which are called from batch files. For audit purposes, I would like to report on the options being passed, and whether they are passed from command line, default, or some other means, to a log file.

Using defaults you can tell whether an option matches a default value, but that still doesn't tell you whether it was actually supplied from command line. This can be relevant: if an option is passed from command line and agrees with the default, if you then change the default in the code the script will still get the same value.

To me it would feel quite natural to have an equivalent to defaults, containing the values actually supplied.

To make the question concrete, in this example:

>>> sys.argv = ['myscript.py','-a','xxx']
>>> import optparse
>>> parser = optparse.OptionParser()
>>> parser.add_option('-a', default = 'xxx')
>>> parser.add_option('-b', default = 'yyy')

How do I know that option a was passed from command line. Is the only way to parse the command line manually?

(I know this is a fairly minor point, but I thought it would be worth asking in case I'm missing smthing on optparse)

Thanks again


回答1:


Instead of the below boilerplate code:

opts, args = parser.parse_args()

if you use the below code, you will have an additional values object opts_no_defaults with options that were explicitly specified by the user:

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

At the end, opts should be identical as in the initial boilerplate code.

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



回答2:


Not knowing you code is impossible to give the better answer, but...

  1. simply don't pass defaults to the parser and check for None values. A None value is a default for optparse lib so you can retrieve your own default and act as usually;

  2. extend optparse to specialize it.

I don't know your program but usually it is not a good design changing behavior when the configuration is the same.




回答3:


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    

Usage:

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"

It would be great if Python maintainers included the suggested function to OptionParser class.



来源:https://stackoverflow.com/questions/2593257/how-to-know-if-optparse-option-was-passed-in-the-command-line-or-as-a-default

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!