usage parser mutually float exclusive example argumentparser argument add_argument python command-line command-line-arguments

parser - Python: ¿Cómo hacer una opción para ser requerida en optparse?



parser python example (9)

Como el módulo optparse está en desuso desde la versión 2.7, probablemente encontrará algunos ejemplos más actualizados aquí: Ejemplo de argparse muerto simple deseado: 1 argumento, 3 resultados

Leí este http://docs.python.org/release/2.6.2/library/optparse.html

Pero no estoy tan claro cómo hacer una opción para ser requerida en optparse?

Intenté establecer "required = 1" pero recibí un error:

argumentos inválidos de palabra clave: requeridos

Quiero que mi script requiera --file opción de --file sea ​​ingresada por los usuarios. Sé que la palabra clave action le da error cuando no proporciona valor a --file cuya action="store_true" .


Dado que if not x no funciona para algunos parámetros (negativo, cero),

y para evitar muchas pruebas si, prefiero algo como esto:

required="host username password".split() parser = OptionParser() parser.add_option("-H", ''--host'', dest=''host'') parser.add_option("-U", ''--user'', dest=''username'') parser.add_option("-P", ''--pass'', dest=''password'') parser.add_option("-s", ''--ssl'', dest=''ssl'',help="optional usage of ssl") (options, args) = parser.parse_args() for r in required: if options.__dict__[r] is None: parser.error("parameter %s required"%r)


En el mensaje de ayuda de cada variable requerida estoy escribiendo una cadena ''[REQUERIDO]'' al principio, para etiquetarla para que sea analizada más tarde, entonces simplemente puedo usar esta función para envolverla:

def checkRequiredArguments(opts, parser): missing_options = [] for option in parser.option_list: if re.match(r''^/[REQUIRED/]'', option.help) and eval(''opts.'' + option.dest) == None: missing_options.extend(option._long_opts) if len(missing_options) > 0: parser.error(''Missing REQUIRED parameters: '' + str(missing_options)) parser = OptionParser() parser.add_option("-s", "--start-date", help="[REQUIRED] Start date") parser.add_option("-e", "--end-date", dest="endDate", help="[REQUIRED] End date") (opts, args) = parser.parse_args([''-s'', ''some-date'']) checkRequiredArguments(opts, parser)


Estoy obligado a usar Python 2.6 para nuestra solución, así que me quedo con el módulo optparse. Aquí hay una solución que encontré para verificar las opciones requeridas que funcionan sin especificar una segunda lista de opciones requeridas. Por lo tanto, cuando agrega una nueva opción, no tiene que agregar su nombre en la lista de opciones para verificar.

Mi criterio para la opción requerida - el valor de la opción no debe ser None y esta opción no tiene el valor predeterminado (el usuario no especificó add_option (default = "...", ...).

def parse_cli(): """parse and check command line options, shows help message @return: dict - options key/value """ import __main__ parser = OptionParser(description=__main__.__doc__) parser.add_option("-d", "--days", dest="days", help="Number of days to process") parser.add_option("-p", "--period", dest="period_length",default="2", help="number or hours per iteration, default value=%default hours") (options, args) = parser.parse_args() """get dictionary of options'' default values. in this example: { ''period_length'': ''2'',''days'': None}""" defaults = vars(parser.get_default_values()) optionsdict = vars(options) all_none = False for k,v in optionsdict.items(): if v is None and defaults.get(k) is None: all_none = True if all_none: parser.print_help() sys.exit() return optionsdict


Hay al menos dos métodos para implementar las opciones requeridas con optparse . Como se menciona en la página de documentos , optparse no impide que implemente las opciones requeridas, pero tampoco le brinda mucha ayuda. Encuentre a continuación los ejemplos encontrados en los archivos distribuidos con la fuente.

Aunque tenga en cuenta que el módulo optparse está en desuso desde la versión 2.7 y no se desarrollará más. Deberías usar el módulo argparse lugar.

Versión 1: Agregue un método a OptionParser al cual las aplicaciones deben llamar después de analizar los argumentos:

import optparse class OptionParser (optparse.OptionParser): def check_required (self, opt): option = self.get_option(opt) # Assumes the option''s ''default'' is set to None! if getattr(self.values, option.dest) is None: self.error("%s option not supplied" % option) parser = OptionParser() parser.add_option("-v", action="count", dest="verbose") parser.add_option("-f", "--file", default=None) (options, args) = parser.parse_args() print "verbose:", options.verbose print "file:", options.file parser.check_required("-f")

Fuente: docs/lib/required_1.txt

Versión 2: amplíe la opción y agregue un atributo requerido; extienda OptionParser para asegurarse de que las opciones requeridas estén presentes después del análisis:

import optparse class Option (optparse.Option): ATTRS = optparse.Option.ATTRS + [''required''] def _check_required (self): if self.required and not self.takes_value(): raise OptionError( "required flag set for option that doesn''t take a value", self) # Make sure _check_required() is called from the constructor! CHECK_METHODS = optparse.Option.CHECK_METHODS + [_check_required] def process (self, opt, value, values, parser): optparse.Option.process(self, opt, value, values, parser) parser.option_seen[self] = 1 class OptionParser (optparse.OptionParser): def _init_parsing_state (self): optparse.OptionParser._init_parsing_state(self) self.option_seen = {} def check_values (self, values, args): for option in self.option_list: if (isinstance(option, Option) and option.required and not self.option_seen.has_key(option)): self.error("%s not supplied" % option) return (values, args) parser = OptionParser(option_list=[ Option("-v", action="count", dest="verbose"), Option("-f", "--file", required=1)]) (options, args) = parser.parse_args() print "verbose:", options.verbose print "file:", options.file

Fuente: docs/lib/required_2.txt


La respuesta actual con la mayoría de los votos no funcionaría si, por ejemplo, el argumento fuera un entero o flotante para el cual cero es una entrada válida. En estos casos, diría que hay un error. Una alternativa (para agregar a los otros aquí) sería hacer, por ejemplo

parser = OptionParser(usage=''usage: %prog [options] arguments'') parser.add_option(''-f'', ''--file'', dest=''filename'') (options, args) = parser.parse_args() if ''filename'' not in options.__dict__: parser.error(''Filename not given'')


Puede implementar una opción requerida fácilmente.

parser = OptionParser(usage=''usage: %prog [options] arguments'') parser.add_option(''-f'', ''--file'', dest=''filename'', help=''foo help'') (options, args) = parser.parse_args() if not options.filename: # if filename is not given parser.error(''Filename not given'')


También estoy atascado en Python 2.6 (pining para python2.7 y argparse, que no solo tiene argumentos obligatorios, sino que también me permite especificar que se debe proporcionar uno de un conjunto); mi enfoque requiere un segundo pase, pero me permite pedir argumentos faltantes a menos que se ejecute en modo por lotes:

# from myscript import helpers import globalconfig parser = optparse.OptionParser(usage=myheader,epilog=myfooter) parser.add_option("-L","--last", action="store",dest="last_name",default="", help="User''s last (family) name; prompted for if not supplied" ) parser.add_option("-y","--yes", action="store_true",dest="batch_flag",default=False, help="don''t prompt to confirm actions (batch mode)" ) [...] (options, args) = parser.parse_args() globalconfig.batchmode = options.batch_flag [...] last = prompt_if_empty(options.last_name, "Last name (can supply with /"-L/" or /"--last/" option):") # from helpers.py def prompt_if_empty(variable,promptstring): if not variable: if globalconfig.batchmode: raise Exception(''Required variable missing.'') print "%s" %promptstring variable = raw_input(globalconfig.prompt) return variable

(Estoy pensando en crear mi propia clase de analizador que tenga opciones comunes para configuraciones globales integradas).

Otra respuesta a esta pregunta citó a parser.error, con el que no estaba familiarizado cuando escribí el código, pero podría haber sido una mejor opción.


Utilizaría la biblioteca argparse que tiene esta funcionalidad incrustada:

PARSER.add_argument("-n", "--namespace", dest="namespace", required=True, help="The path within the repo to the data base")

referencia argparse