On peut parser sys.argv
à la main, mais c’est fragile.
On peut utiliser getopt ou optpase, mais c’est déprécié.
On peut adopter le nouveau module de la stdlib, vers argparse, mais c’est compliqué.
Alors j’installais toujours clize.
Mais depuis que j’ai rencontré docopt, j’ai largué clize (c’est pas moi chérie, c’est toi) et on vit en amoureux tous les deux en élevant des scripts dans une ferme dans les Alpes.
pip install docopt |
Docopt fonctionne à l’envers de la plupart des libs de ce genre : vous écrivez le message d’aide de votre script, et ça génère le parsing des arguments. La syntaxe de l’aide est de type posix, donc si vous avez utilisez un -h
ou la commande man
un jour, vous la connaissez déjà.
Voici comment ça marche :
help = """Le nom de mon programme trop cool Usage: nom_du_script.py <argument_positionel> [<argument_positionel_optionel>] [--flag-optionel] Options: -h --help C'est généré automatiquement. --option=<valeur> Description de l'option. Woot, un footer ! """ from docopt import docopt arguments = docopt(help) print(arguments) |
Si on passe rien de valide au script, l’usage est affiché automatiquement :
$ python nom_du_script.py Usage: nom_du_script.py <argument_positionel> [<argument_positionel_optionel>] [--flag-optionel] |
Si on demande l’aide, en option, ben, l’aide quoi :
$ python nom_du_script.py -h Le nom de mon programme trop cool Usage: nom_du_script.py <argument_positionel> [<argument_positionel_optionel>] [--flag-optionel] Options: -h --help C'est généré automatiquement. --option=<valeur> Description de l'option. Woot, un footer ! |
Et si on passe des arguments, on les récupère dans un simple dictionnaire :
$ python nom_du_script.py yo {'--flag-optionel': False, '<argument_positionel>': 'yo', '<argument_positionel_optionel>': None} $ python nom_du_script.py yo man {'--flag-optionel': False, '<argument_positionel>': 'yo', '<argument_positionel_optionel>': 'man'} $ python nom_du_script.py yo --flag-optionel {'--flag-optionel': True, '<argument_positionel>': 'yo', '<argument_positionel_optionel>': None} |
Ça peut générer des choses complexes avec des tas de combinaisons d’options, des sous-commandes et tout le bordel.
Généralement on en profite pour faire ça proprement, en mettant l’usage en docstring du script, en calant une version et en rajoutant un if __main__
:
"""Uber script. Usage: schnell.py scheisse schnell.py bier Options: -h --help _o/ --version \o_ --blitz=krieg \o/ """ from docopt import docopt if __name__ == '__main__': # __doc__ contient automatiquement la docstring du module # en cours arguments = docopt(__doc__, version='0.1') print(arguments) |
$ python schnell.py --version 0.1 $ python schnell.py bier {'bier': True, 'scheisse': False} |
C’est chiant; je suis sûr et certain que ça peut m’être utile, mais je n’arrive pas à comprendre comment ni pourquoi. En attendant, typos:
on option -> en option
on les récupères -> on les récupère
en callant -> en calant
Quand tu voudras faire des scripts configurables, ça t’évitera de galérer à parser les options, c’est tout. Scripts de sysadmin, migration de base de données, etc.
Typos corrigées :)
Content de voir qu’il est enfin dispo sur pip, ça manquait la dernière fois que je l’ai utilisé.
t’as l’air fin si tu fais :
python scriptatouille.py -h
puisque ca va donner
Usage:
schnell.py scheisse
schnell.py bier
or tu tapes pas python schnell.py mais python scriptatouille.py :) allez => raus :)
Lol, désolé, je vire cette erreur de copier / coller.
J’aimerais rajouter que même si c’est en python que le mariage est le mieux réussi à mon avis, docopt existe également pour beaucoup d’autres langages comme ruby, le php, le C, le C++ et même le bash !
Voir le github du projet docopt pour plus d’informations.
(Et la video de présentation est trop bien !)
T’écris la doc, ça génère le code… plus aucune raison d’éviter les docstring…
à cause de vous, des fois, je me demande si j’utilise vos trucs dans mes codes, ou si je code juste pour avoir le plaisir d’utiliser vos trucs..
en tout cas, merci pour tout et continuez!
Ca me fait aussi cet effet. Souvent je code juste pour tester un nouveau joujou, et paf, merde alors, j’ai crée un nouveau projet.
J’aime bien argparse moi, comme je fais toujours des scripts simples j’ai jamais eu de souci. Et c’est très proche de optparse (pour mon utilisation en tout cas). Et puis on peut lui indiquer le type de données qu’il accepte pour une option, donc si je demande un int j’aurai un int (et pas une string à parser), et si c’est pas un int qui est passé ça geulera tout seul à l’exécution en affichant l’aide.
Cela dit le concept de ce truc est intéressant.
Perso je suis fan et totalement addicte mais j’aimerais pouvoir mettre le script en background avec mon “&” une idée?
En fait un nohup fait l’affaire mais quand même je trouve ma question intéressante :p
Bon alors personne? Pas une idée brillante par ici?
Ok visiblement les types de ce bog préfère visiblement se “tater la tentacule en plastique en criant Yameru, Kyōju-Sama !”.
Alors dans l’ordre :
– Tu expliques la moitié de ton problème visiblement puisque avec ce script:
Et en lançant :
python essai.py ship new test &
Ca se met bien en arrière plan, je viens de le tester.
Pour t’aider il faudrait donc que tu suives ceci.
– Il s’agit d’un problème lié à bash, pas particulièrement à cette lib. Tu viens donc raler au mauvais endroit. Qui plus est en comment plutôt que sur un forum d’aide.
– En prime, tu demandes de l’aide en insultant les gens.
Bref, tu mérite un tampon.
Merci! Cool mon premier tampon! Je ne voulais pas être insultante je m’excuse si c’était mal perçu, ca n’était pas mon intention…je voulais juste rire un peu en faisant un clin d’oeil sur votre
dernieravant-dernier articleSoyons honnête, je préfère me tater la tentacule à bien des choses. Pardonnée, mais le tampon reste, parce que j’aime les tampons.
This post save my day. Thanks.
Vraiment très cool, comme toujours, c’est ce que je cherchais. Par contre (je sais que c’est relou), ce serait cool du coup que vous mettiez à jour les articles comme “Sept petites libs qui changent la vie d’un dev Python”. Les gens peuvent tomber dessus, commencer avec clize, avant de tomber sur ce nouvel article qui parle de docopt. Enfin c’est juste une suggestion…
Clize a toujours sa place IMO.
Merci pour cet article qui m’a permis de découvrir et apprécier docopt. Encore une lecture intéressante chez Sam&Max !
Ce petit mot pour vous signaler ConfigArgParse> qui est moins élégant et facile à utiliser mais qui vient avec la gestion automatique des arguments dans un fichier de configuration et dans l’environnement.
Je me suis mélangé dans le lien du comment précédent : le lien pointe vers configargparse.
Bonjour,
Tout d’abord merci beaucoup pour tous ces articles. Ils sont d’une grande qualité et c’est mon go-to en informatique.
J’ai effectué pas mal de recherche à propos de deux sujets en lien avec cet article et j’avoue ne pas avoir trouvé mon bonheur sur le net. Je profite de ce post pour demander de l’aide à une âme charitable.
Le premier serait la notation utilisée pour décrire l’usage de scripts/commandes/fonctions dans les documents techniques
et également dans les docstrings. Dans l’exemple de Sam, “Naval Fate” contient
"""Naval Fate. Usage: naval_fate.py ship new ... naval_fate.py ship move [--speed=] naval_fate.py ship shoot naval_fate.py mine (set|remove) [--moored | --drifting] naval_fate.py (-h | --help) naval_fate.py --version Options: -h --help Show this screen. --version Show version. --speed= Speed in knots [default: 10]. --moored Moored (anchored) mine. --drifting Drifting mine. """
Comment se décortique l’usage des “[, (, {, | ” par exemple? Est ce qu’il y a une convention standard décrite quelque part qui concernerait toute l’informatique en général?
Le deuxième sujet concerne le parsing des arguments en ligne de commande. Le module argparse de python semble dire qu’il suit la norme/le standard GNU/POSIX. les recherches sur le net dirigent sans cesse vers des librairies de parsing d’arguments de la ligne de commande pour des langages particuliers. Existe t il un standard langage agnostic qui décrit le parsing des arguments de la ligne de commande avec un document assez clair qui l’expliquerait? Le document (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html) semble aller dans ce sens, mais ne comprenant pas le sujet 1, j’ai du mal à décrypter ce document assez technique.
Merci d’avance pour toute aide dans ma quête de connaissances
Y a un bon article a faire en effet. J’avais eu la même question quand j’ai débuté en informatique, et j’ai juste oublié que j’avais galéré là dessus.
Pour le standard, je n’en connais pas. Ce sont des infos que j’ai glané à l’usage.