web-dev-qa-db-fra.com

Exemple simple recherché: 1 argument, 3 résultats

Le documentation pour le argparse python module , bien qu'excellent, j'en suis certain, c'est trop pour mon petit cerveau de débutant à saisir maintenant. Je n'ai pas besoin de faire des calculs sur la ligne de commande, de modifier les lignes de formatage à l'écran ou de modifier les caractères d'option. Tout ce que je veux faire est "Si arg est A, fais ceci, si B le fait, si aucun des éléments ci-dessus ne montre l'aide et ne quitte" .

497
matt wilkie

Ma compréhension de la question initiale est double. Premièrement, en ce qui concerne l'exemple le plus simple possible, je suis surpris de ne pas l'avoir vu ici. Bien sûr, pour être tout simple, il s’agit également de frais généraux avec peu de puissance, mais cela peut vous aider à démarrer.

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()

if args.a == 'magic.name':
    print 'You nailed it!'

Mais cet argument de position est maintenant requis. Si vous ne l'utilisez pas lorsque vous appelez ce programme, vous obtiendrez une erreur concernant les arguments manquants. Cela m'amène à la deuxième partie de la question initiale. Matt Wilkie semble vouloir un seul argument facultatif sans étiquette nommée (les étiquettes --option). Ma suggestion serait de modifier le code ci-dessus comme suit:

...
parser.add_argument("a", nargs='?', default="check_string_for_empty")
...
if args.a == 'check_string_for_empty':
    print 'I can tell that no argument was given and I can deal with that here.'
Elif args.a == 'magic.name':
    print 'You nailed it!'
else:
    print args.a

Il y a peut-être une solution plus élégante, mais cela fonctionne et est minimaliste.

236
mightypile

Voici comment je le fais avec argparse (avec plusieurs arguments):

parser = argparse.ArgumentParser(description='Description of your program')
parser.add_argument('-f','--foo', help='Description for foo argument', required=True)
parser.add_argument('-b','--bar', help='Description for bar argument', required=True)
args = vars(parser.parse_args())

args sera un dictionnaire contenant les arguments:

if args['foo'] == 'Hello':
    # code here

if args['bar'] == 'World':
    # code here

Dans votre cas, ajoutez simplement un seul argument.

344
Diego Navarro

La documentation argparse est raisonnablement bonne mais laisse de côté quelques détails utiles qui peuvent ne pas être évidents. (@Diego Navarro en a déjà parlé, mais je vais essayer de développer légèrement sa réponse.) L'utilisation de base est la suivante:

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()

L'objet que vous récupérez de parse_args() est un objet 'Namespace': un objet dont les variables de membre portent le nom de vos arguments de ligne de commande. L'objet Namespace vous permet d'accéder à vos arguments et aux valeurs qui leur sont associées:

args = parser.parse_args()
print args.my_foo
print args.bar_value

(Notez que argparse remplace les caractères '-' dans les noms de vos arguments par des traits de soulignement lors de la désignation des variables.)

Dans de nombreuses situations, vous voudrez peut-être utiliser des arguments simplement comme des indicateurs qui n’ont aucune valeur. Vous pouvez ajouter ceux dans argparse comme ceci:

parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')

Ce qui précède créera des variables nommées "foo" avec la valeur True et "no_foo" avec la valeur False, respectivement:

if (args.foo):
    print "foo is true"

if (args.no_foo is False):
    print "nofoo is false"

Notez également que vous pouvez utiliser l'option "required" lorsque vous ajoutez un argument:

parser.add_argument('-o', '--output', required=True)

Ainsi, si vous omettez cet argument sur la ligne de commande, argparse vous indiquera son absence et arrêtera l'exécution de votre script.

Enfin, notez qu’il est possible de créer une structure dict de vos arguments à l’aide de la fonction vars, si cela vous simplifie la vie.

args = parser.parse_args()
argsdict = vars(args)
print argsdict['my_foo']
print argsdict['bar_value']

Comme vous pouvez le constater, vars renvoie un dict avec les noms de vos arguments en tant que clés et leurs valeurs en tant que, valeurs, etc.

Il y a beaucoup d'autres options et choses que vous pouvez faire, mais cela devrait couvrir les scénarios d'utilisation les plus essentiels et les plus courants.

199
DMH

Matt demande des informations sur les paramètres de position dans argparse, et je conviens que la documentation Python fait défaut sur cet aspect. Il n’ya pas un seul exemple complet dans les ~ 20 pages impaires qui montre les deux analyse et utilisation de paramètres de position.

Aucune des autres réponses ici ne montre un exemple complet de paramètres de position, alors voici un exemple complet:

# tested with python 2.7.1
import argparse

parser = argparse.ArgumentParser(description="An argparse example")

parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')

args = parser.parse_args()

if args.action == "install":
    print("You asked for installation")
else:
    print("You asked for something other than installation")

# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)

# But this works:
print(getattr(args, 'foo-bar'))

Ce qui m’a jeté à terre, c’est que argparse va convertir l’argument nommé "--foo-bar" en "foo_bar", mais un paramètre de position nommé "foo-bar" reste en tant que "foo-bar", ce qui rend moins évident comment utilisez-le dans votre programme.

Remarquez les deux lignes vers la fin de mon exemple - aucune de celles-ci ne fonctionnera pour obtenir la valeur du paramètre positionnel foo-bar. Le premier est évidemment faux (c'est une expression arithmétique args.foo moins barre), mais le second ne fonctionne pas non plus:

AttributeError: 'Namespace' object has no attribute 'foo_bar'

Si vous souhaitez utiliser l'attribut foo-bar, vous devez utiliser getattr, comme indiqué dans la dernière ligne de mon exemple. Ce qui est fou, c'est que si vous tentiez d'utiliser dest=foo_bar pour changer le nom de la propriété en quelque chose de plus accessible, vous obtiendrez un message d'erreur vraiment bizarre:

ValueError: dest supplied twice for positional argument

Voici comment fonctionne l'exemple ci-dessus:

$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments

$ python test.py -h
usage: test.py [-h] action foo-bar

An argparse example

positional arguments:
  action      The action to take (e.g. install, remove, etc.)
  foo-bar     Hyphens are cumbersome in positional arguments

optional arguments:
  -h, --help  show this help message and exit

$ python test.py install foo
You asked for installation
foo
56
Mark E. Haase

Encore une autre introduction sommaire, inspirée par ce post .

import argparse

# define functions, classes, etc.

# executes when your script is called from the command-line
if __== "__main__":

    parser = argparse.ArgumentParser()
    #
    # define each option with: parser.add_argument
    #
    args = parser.parse_args() # automatically looks at sys.argv
    #
    # access results with: args.argumentName
    #

Les arguments sont définis avec des combinaisons des éléments suivants:

parser.add_argument( 'name', options... )              # positional argument
parser.add_argument( '-x', options... )                # single-char flag
parser.add_argument( '-x', '--long-name', options... ) # flag with long name

Les options communes sont:

  • help : description de cet argument lorsque --help est utilisé.
  • valeur par défaut : valeur par défaut si l'argument est omis.
  • type : si vous attendez float ou int (sinon str).
  • dest : donnez un nom différent à un drapeau (par exemple, '-x', '--long-name', dest='longName').
    Remarque: par défaut, --long-name est accessible avec args.long_name.
  • action : pour un traitement spécial de certains arguments
    • store_true, store_false: pour les arguments booléens
      '--foo', action='store_true' => args.foo == True
    • store_const: à utiliser avec l'option const
      '--foo', action='store_const', const=42 => args.foo == 42
    • count: pour les options répétées, comme dans ./myscript.py -vv
      '-v', action='count' => args.v == 2
    • append: pour les options répétées, comme dans ./myscript.py --foo 1 --foo 2
      '--foo', action='append' => args.foo == ['1', '2']
  • requis : si un drapeau est requis, ou un argument de position ne l'est pas.
  • nargs : pour un drapeau capturant N args
    ./myscript.py --foo a b => args.foo = ['a', 'b']
  • choix : pour limiter les entrées possibles (spécifier comme liste de chaînes, ou ints si type=int).
16
Sheljohn

Notez le Tutoriel Argparse dans Python HOWTOs . Il part des exemples les plus élémentaires, comme celui-ci:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)

et progresse vers les moins fondamentaux.

Il existe un exemple avec un choix prédéfini pour une option, comme ce qui est demandé:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print("the square of {} equals {}".format(args.square, answer))
Elif args.verbosity == 1:
    print("{}^2 == {}".format(args.square, answer))
else:
    print(answer)
11
Alexey

Voici ce que j’ai trouvé dans mon projet d’apprentissage, principalement grâce à @DMH ...

Code de démonstration:

import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-f', '--flag', action='store_true', default=False)  # can 'store_false' for no-xxx flags
    parser.add_argument('-r', '--reqd', required=True)
    parser.add_argument('-o', '--opt', default='fallback')
    parser.add_argument('arg', nargs='*') # use '+' for 1 or more args (instead of 0 or more)
    parsed = parser.parse_args()
    # NOTE: args with '-' have it replaced with '_'
    print('Result:',  vars(parsed))
    print('parsed.reqd:', parsed.reqd)

if __== "__main__":
    main()

Cela peut avoir évolué et est disponible en ligne: command-line.py

Script pour donner à ce code un entraînement: command-line-demo.sh

10
Peter L

Pour ajouter à ce que d’autres ont dit:

J'aime généralement utiliser le paramètre 'dest' pour spécifier un nom de variable, puis utiliser 'globals (). Update ()' pour mettre ces variables dans l'espace de noms global.

Usage:

$ python script.py -i "Hello, World!"

Code:

...
parser.add_argument('-i', '--input', ..., dest='inputted_variable',...)
globals().update(vars(parser.parse_args()))
...
print(inputted_variable) # Prints "Hello, World!"
4
Sandy Chapman

Vous pouvez aussi utiliser plac (un wrapper autour de argparse).

En prime, il génère des instructions d’aide soignées - voir ci-dessous.

Exemple de script:

#!/usr/bin/env python3
def main(
    arg: ('Argument with two possible values', 'positional', None, None, ['A', 'B'])
):
    """General help for application"""
    if arg == 'A':
        print("Argument has value A")
    Elif arg == 'B':
        print("Argument has value B")

if __== '__main__':
    import plac
    plac.call(main)

Exemple de sortie:

Aucun argument fourni - example.py:

usage: example.py [-h] {A,B}
example.py: error: the following arguments are required: arg

Argument inattendu fourni - example.py C:

usage: example.py [-h] {A,B}
example.py: error: argument arg: invalid choice: 'C' (choose from 'A', 'B')

Argument correct fourni - example.py A:

Argument has value A

Menu d’aide complet (généré automatiquement) - example.py -h:

usage: example.py [-h] {A,B}

General help for application

positional arguments:
  {A,B}       Argument with two possible values

optional arguments:
  -h, --help  show this help message and exit

Brève explication:

Le nom de l'argument est généralement égal au nom du paramètre (arg).

L'annotation Tuple after arg a la signification suivante:

  • Description (Argument with two possible values)
  • Type d'argument - un de 'drapeau', 'option' ou 'positional' (positional)
  • Abréviation (None)
  • Type de valeur d'argument - par exemple. float, string (None)
  • Ensemble de choix restreint (['A', 'B'])

Documentation:

Pour en savoir plus sur l'utilisation de plac , consultez sa documentation:

Plac: Analyser la ligne de commande en toute simplicité

4
quasoft

Un moyen très simple d'utiliser argparse et de modifier les commutateurs '-h'/'--help' pour afficher vos propres instructions d'aide de code personnel consiste à définir l'aide par défaut sur False. Vous pouvez également ajouter autant d'arguments .add_arguments que vous le souhaitez. :

import argparse

parser = argparse.ArgumentParser(add_help=False)

parser.add_argument('-h', '--help', action='help',
                help='To run this script please provide two arguments')
parser.parse_args()

Exécuter: python test.py -h

Sortie:

usage: test.py [-h]

optional arguments:
  -h, --help  To run this script please provide two arguments
1
Hutch