282 votes

Quelle est la meilleure façon d'analyser les arguments de la ligne de commande ?

Quel est le le plus facile , le plus petit et la plupart flexible une méthode ou une bibliothèque pour analyser les arguments de la ligne de commande Python ?

201voto

Thomas Vander Stichele Points 16872

Cette réponse suggère optparse qui est approprié pour les anciennes versions de Python. Pour Python 2.7 et plus, argparse remplace optparse . Voir cette réponse pour plus d'informations.

Comme d'autres personnes l'ont souligné, il est préférable d'utiliser optparse plutôt que getopt. getopt est en fait une correspondance un-à-un des fonctions standard de la bibliothèque C getopt(3), et n'est pas très facile à utiliser.

optparse, tout en étant un peu plus verbeux, est beaucoup mieux structuré et plus simple à étendre par la suite.

Voici une ligne typique pour ajouter une option à votre analyseur syntaxique :

parser.add_option('-q', '--query',
            action="store", dest="query",
            help="query string", default="spam")

Elle parle d'elle-même ; au moment du traitement, elle accepte -q ou --query comme options, stocke l'argument dans un attribut appelé query et a une valeur par défaut si vous ne la spécifiez pas. Il est également auto-documenté dans la mesure où vous déclarez l'argument help (qui sera utilisé lors de l'exécution avec -h/--help) directement avec l'option.

D'habitude, tu parsages tes arguments avec :

options, args = parser.parse_args()

Cela va, par défaut, analyser les arguments standard passés au script (sys.argv[1 :]).

options.query sera alors défini à la valeur que vous avez passée au script.

Vous créez un analyseur simplement en faisant

parser = optparse.OptionParser()

Voici les éléments de base dont vous avez besoin. Voici un script Python complet qui le montre :

import optparse

parser = optparse.OptionParser()

parser.add_option('-q', '--query',
    action="store", dest="query",
    help="query string", default="spam")

options, args = parser.parse_args()

print 'Query string:', options.query

5 lignes de python qui vous montrent les bases.

Enregistrez-le dans sample.py, et exécutez-le une fois avec

python sample.py

et une fois avec

python sample.py --query myquery

Au-delà de cela, vous trouverez qu'optparse est très facile à étendre. Dans un de mes projets, j'ai créé une classe Command qui vous permet d'imbriquer facilement des sous-commandes dans un arbre de commande. Elle utilise fortement optparse pour enchaîner les commandes. Ce n'est pas quelque chose que je peux facilement expliquer en quelques lignes, mais n'hésitez pas à naviguer dans mon référentiel pour la classe principale, ainsi que une classe qui l'utilise et le parseur d'options

10 votes

Cette réponse est merveilleusement claire et facile à suivre -- pour python 2.3 à 2.6. Pour python 2.7+, ce n'est pas la meilleure réponse car argparse fait maintenant partie de la bibliothèque standard et optparse est déprécié.

0 votes

Dans mon cas, je veux profiler mon application pour détecter la lenteur. Il existe un autre outil appelé [tuna] ( github.com/nschloe/tuna ) qui me permet de profiler l'ensemble de l'application en ajoutant simplement des agrs. -mcProfile -o program.prof mais agrparcer capture ces args, comment puis-je passer ces args à l'exe python ???

83voto

ndemou Points 324

Utilisation de docopt

Depuis 2012, il existe une solution très simple, puissante et vraiment cool pour l'analyse des arguments, appelé docopt . Voici un exemple tiré de sa documentation :

"""Naval Fate.

Usage:
  naval_fate.py ship new <name>...
  naval_fate.py ship <name> move <x> <y> [--speed=<kn>]
  naval_fate.py ship shoot <x> <y>
  naval_fate.py mine (set|remove) <x> <y> [--moored | --drifting]
  naval_fate.py (-h | --help)
  naval_fate.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
  --speed=<kn>  Speed in knots [default: 10].
  --moored      Moored (anchored) mine.
  --drifting    Drifting mine.

"""
from docopt import docopt

if __name__ == '__main__':
    arguments = docopt(__doc__, version='Naval Fate 2.0')
    print(arguments)

C'est donc ça : 2 lignes de code plus votre chaîne de caractères qui es essentiel et vous obtenez vos arguments analysés et disponibles dans votre objet arguments.

Utilisation de python-fire

Depuis 2017, il existe un autre module sympa appelé feu python . Il peut générer une interface CLI pour votre code sans que vous ayez à faire quoi que ce soit. zéro l'analyse des arguments. Voici un exemple simple tiré de la documentation (ce petit programme expose la fonction double à la ligne de commande) :

import fire

class Calculator(object):

  def double(self, number):
    return 2 * number

if __name__ == '__main__':
  fire.Fire(Calculator)

Depuis la ligne de commande, vous pouvez exécuter :

> calculator.py double 10
20
> calculator.py double --number=15
30

4 votes

Comment docopt peut-il "ne pas nécessiter d'installation" ? c'est un module python donc il doit être installé. ImportError : Aucun module nommé docopt'.

1 votes

@keen il n'est pas inclus avec python pour sûr mais vous n'avez pas besoin de l'installer : "vous pouvez simplement déposer le fichier docopt.py dans votre projet - il est autonome" -- github.com/docopt/docopt

11 votes

Nous avons simplement des définitions différentes de l'installation - et je voulais le souligner pour les futurs lecteurs.

39voto

Silfheed Points 2818

La nouvelle mode est argparse para ces raisons. argparse > optparse > getopt

mettre à jour : À partir de py2.7 argparse fait partie de la bibliothèque standard et optparse est déprécié.

0 votes

Votre lien principal est 404, je l'ai donc remplacé par un lien vers une question SO qui traite du même sujet.

14voto

Corey Points 5286

Utilisez optparse qui est fourni avec la bibliothèque standard. Par exemple :

#!/usr/bin/env python
import optparse

def main():
  p = optparse.OptionParser()
  p.add_option('--person', '-p', default="world")
  options, arguments = p.parse_args()
  print 'Hello %s' % options.person

if __name__ == '__main__':
  main()

Source : Utilisation de Python pour créer des outils de ligne de commande UNIX

Cependant, à partir de Python 2.7, optparse est déprécié, voir : Pourquoi utiliser argparse plutôt qu'optparse ?

14voto

fulmicoton Points 5389

Presque tout le monde utilise getopt

Voici l'exemple de code pour la doc :

import getopt, sys

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "ho:v", ["help", "output="])
    except getopt.GetoptError:
        # print help information and exit:
        usage()
        sys.exit(2)
    output = None
    verbose = False
    for o, a in opts:
        if o == "-v":
            verbose = True
        if o in ("-h", "--help"):
            usage()
            sys.exit()
        if o in ("-o", "--output"):
            output = a

En un mot, voici comment cela fonctionne.

Vous avez deux types d'options. Celles qui reçoivent des arguments, et celles qui sont juste des interrupteurs.

sys.argv est à peu près votre char** argv en C. Comme en C, vous sautez le premier élément qui est le nom de votre programme et n'analysez que les arguments : sys.argv[1:]

Getopt.getopt l'analysera selon la règle que vous donnez en argument.

"ho:v" Voici la description des arguments courts : -ONELETTER . Le site : signifie que -o accepte un argument.

Enfin ["help", "output="] décrit les arguments longs ( --MORETHANONELETTER ). Le site = après output signifie encore une fois que output accepte un argument.

Le résultat est une liste de couple (option,argument)

Si une option n'accepte aucun argument (comme --help ici) le arg est une chaîne vide. Vous voulez ensuite généralement boucler sur cette liste et tester le nom de l'option comme dans l'exemple.

J'espère que cela vous a aidé.

6 votes

Avec la dépréciation de getopt dans les nouvelles versions de Python, cette réponse n'est plus d'actualité.

1 votes

@shuttle87 A partir de python3.7.2, getopt n'est toujours pas déprécié Mais sa documentation précise qu'il est principalement destiné aux utilisateurs familiers du C getopt() et reconnaît que pour d'autres utilisateurs argparse pourrait être une meilleure solution, permettant "d'écrire moins de code et d'obtenir de meilleurs messages d'aide et d'erreur".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X