Как узнать, была ли опция optparse передана в командной строке или по умолчанию - PullRequest
8 голосов
/ 07 апреля 2010

Используя python optparse.py, есть ли способ выяснить, было ли задано конкретное значение параметра из командной строки или из значения по умолчанию.

В идеале я хотел бы иметь dict как значения по умолчанию, но содержащий параметры, фактически предоставленные из командной строки

Я знаю, что вы можете сравнить значение для каждого параметра со значениями по умолчанию, но это не будет отличать значение, передаваемое через командную строку, которая соответствует значению по умолчанию.

Спасибо!


EDIT

Извините, моя оригинальная формулировка была не очень ясной.

У меня есть большое количество скриптов, которые вызываются из командных файлов. В целях аудита я хотел бы сообщить о передаваемых параметрах и о том, передаются ли они из командной строки, по умолчанию или другими способами, в файл журнала.

Используя значения по умолчанию, вы можете определить, соответствует ли параметр значению по умолчанию, но это еще не говорит о том, был ли он фактически введен из командной строки. Это может иметь значение: если параметр передается из командной строки и согласуется со значением по умолчанию, если вы затем измените значение по умолчанию в коде, сценарий все равно получит то же значение.

Для меня было бы вполне естественным иметь эквивалент значений по умолчанию, содержащий фактически предоставленные значения.

Чтобы конкретизировать вопрос, в этом примере:

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

8 голосов
/ 02 июля 2012

Вместо приведенного ниже стандартного кода:

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))
3 голосов
/ 07 апреля 2010

Не зная вашего кода, невозможно дать лучший ответ, но ...

  1. просто не передает значения по умолчанию парсеру и проверяет None значения. Значение None является значением по умолчанию для optparse lib, поэтому вы можете получить собственное значение по умолчанию и действовать как обычно;

  2. расширить optparse, чтобы специализировать его.

Я не знаю вашу программу, но обычно при изменении конфигурации поведение не очень хорошее.

1 голос
/ 02 мая 2014
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.

...