J'ai lu ceci http://docs.python.org/release/2.6.2/library/optparse.html
Mais je ne sais pas trop comment faire une option qui sera requise dans l'optparse?
J'ai essayé de définir "required = 1" mais j'ai une erreur:
arguments de mots clés non valides: requis
Je veux que mon script nécessite --file
option à saisir par les utilisateurs. Je sais que le mot clé action
vous donne une erreur lorsque vous ne fournissez pas de valeur à --file
dont action="store_true"
.
Vous pouvez facilement implémenter une option requise.
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')
Sur le message d'aide de chaque variable requise En écrivant une chaîne '[REQUIRED]' au début, pour la marquer pour être analysée plus tard, alors je peux simplement utiliser cette fonction pour la boucler:
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)
Puisque if not x
ne fonctionne pas pour certains paramètres (négatifs, zéro),
et pour éviter de nombreux tests if, je préfère quelque chose comme ceci:
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)
L'actuel réponse avec le plus de votes ne fonctionnerait pas si, par exemple, l'argument était un entier ou un flottant pour lequel zéro est une entrée valide. Dans ces cas, il dirait qu'il y a une erreur. Une alternative (à ajouter aux autres ici) serait de faire par exemple.
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')
Je suis obligé d'utiliser python 2.6 pour notre solution, je m'en tiens donc au module optparse. Voici la solution que j'ai trouvée pour vérifier les options requises qui fonctionnent sans spécifier la deuxième fois la liste des options requises. Ainsi, lorsque vous ajoutez une nouvelle option, vous n'avez pas à ajouter son nom dans la liste des options à vérifier.
Mes critères pour l'option requise - la valeur de l'option ne doit pas être None et cette option n'a pas de valeur par défaut (l'utilisateur n'a pas spécifié 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
Il existe au moins deux méthodes d'implémentation des options requises avec optparse
. Comme mentionné dans la page docs , optparse ne vous empêche pas d'implémenter les options requises, mais ne vous donne pas grand-chose aider à elle non plus. Retrouvez ci-dessous les exemples trouvés dans les fichiers distribués avec la source.
Bien que veuillez noter que optparse
module est obsolète depuis la version 2.7 et ne sera pas développé davantage. Vous devez utiliser argparse
module à la place.
Version 1: ajoutez à OptionParser une méthode que les applications doivent appeler après l'analyse des arguments:
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")
La source: docs/lib/required_1.txt
Version 2: étendre l'option et ajouter un attribut requis; étendez OptionParser pour vous assurer que les options requises sont présentes après l'analyse:
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
La source: docs/lib/required_2.txt
Comme le module optparse est obsolète depuis la version 2.7, vous trouverez probablement des exemples plus à jour ici: n exemple d'argparse simple et simple voulait: 1 argument, 3 résultats
Je suis également bloqué sur python 2.6 (pining pour python2.7 et argparse, qui non seulement a des arguments requis, mais me permet de spécifier que l'un d'un ensemble doit être fourni); mon approche nécessite une deuxième passe, mais me permet de demander les arguments manquants, sauf en cas d'exécution en mode batch:
# 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
(Je pense à créer ma propre classe d'analyseur qui a des options communes pour les configurations globales intégrées.)
Une autre réponse à cette question a cité parser.error, que je ne connaissais pas lorsque j'ai écrit le code, mais qui aurait pu être un meilleur choix.