Est-il possible lors de l'utilisation du module argparse d'ajouter une validation lors de l'analyse des arguments?
from argparse import ArgumentParser
parser = ArgumentParser(description='Argument parser for PG restore')
parser.add_argument('--database', dest='database',
default=None, required=False, help='Database to restore')
parser.add_argument('--backup', dest='backup',
required=True, help='Location of the backup file')
parsed_args = parser.parse_args()
Serait-il possible, pour ajouter un contrôle de validation à cet analyseur d'arguments, de s'assurer que le fichier/base de données de sauvegarde existe? Plutôt que d'avoir à ajouter une vérification supplémentaire après cela pour chaque paramètre tel que:
from os.path import exists
if not database_exists(parsed_args.database):
raise DatabaseNotFoundError
if not exists(parsed_args.backup):
raise FileNotFoundError
argparse.FileType
Est une classe d'usine type
qui peut ouvrir un fichier et, bien sûr, dans le processus, générer une erreur si le fichier n'existe pas ou ne peut pas être créé. Vous pouvez regarder son code pour voir comment créer votre propre classe (ou fonction) pour tester vos entrées.
L'argument type
paramètre est un appelable (fonction, etc.) qui prend une chaîne, la teste selon les besoins et la convertit (selon les besoins) en le type de valeur que vous souhaitez enregistrer dans args
espace de noms. Il peut donc effectuer tout type de test que vous souhaitez. Si le type
déclenche une erreur, alors l'analyseur crée un message d'erreur (et son utilisation) et quitte.
Maintenant, que ce soit le bon endroit pour faire le test ou non, cela dépend de votre situation. Parfois, ouvrir un fichier avec FileType
est très bien, mais vous devez le fermer vous-même ou attendre la fin du programme. Vous ne pouvez pas utiliser ce fichier ouvert dans un contexte with open(filename) as f:
. La même chose pourrait s'appliquer à votre base de données. Dans un programme complexe, vous ne voudrez peut-être pas ouvrir ou créer le fichier tout de suite.
J'ai écrit pour un Python/émettre une variation sur FileType
qui a créé un context
, un objet qui pourrait être utilisé dans le with
J'ai également utilisé des tests os
pour vérifier si le fichier existait ou pouvait être créé, sans le faire. Mais cela nécessitait d'autres astuces si le file
était stdin/out
que vous ne veut pas fermer. Parfois, essayer de faire des choses comme ça dans argparse
est juste plus de travail que ça vaut la peine.
Quoi qu'il en soit, si vous avez une méthode de test simple, vous pouvez l'encapsuler dans une simple fonction type
comme ceci:
def database(astring):
from os.path import exists
if not database_exists(astring):
raise ValueError # or TypeError, or `argparse.ArgumentTypeError
return astring
parser.add_argument('--database', dest='database',
type = database,
default=None, required=False, help='Database to restore')
Je ne pense pas que cela soit très important que vous implémentiez des tests comme celui-ci dans type
ou Action
. Je pense que le type
est plus simple et plus conforme aux intentions du développeur.
Sûrement! Il vous suffit de spécifier une action personnalisée en tant que classe et de remplacer __call__(..)
. Lien vers la documentation.
Quelque chose comme:
import argparse
class FooAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
if values != "bar":
print "Got value:", values
raise ValueError("Not a bar!")
setattr(namespace, self.dest, values)
parser = argparse.ArgumentParser()
parser.add_argument("--foo", action=FooAction)
parsed_args = parser.parse_args()
Dans votre cas particulier, j'imagine que vous auriez DatabaseAction
et FileAction
(ou quelque chose comme ça).