Buscar..


Introducción

La mayoría de las herramientas de línea de comandos se basan en argumentos pasados ​​al programa en su ejecución. En lugar de solicitar una entrada, estos programas esperan que se establezcan datos o indicadores específicos (que se convierten en valores booleanos). Esto permite que tanto el usuario como otros programas ejecuten el archivo Python pasándole los datos a medida que se inician. Esta sección explica y demuestra la implementación y el uso de los argumentos de la línea de comandos en Python.

Hola mundo en argparse

El siguiente programa dice hola al usuario. Toma un argumento posicional, el nombre del usuario, y también se le puede decir el saludo.

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', 
    help='name of user'
)

parser.add_argument('-g', '--greeting', 
    default='Hello',
    help='optional alternate greeting'
)

args = parser.parse_args()

print("{greeting}, {name}!".format(
       greeting=args.greeting,
       name=args.name)
)
$ python hello.py --help
usage: hello.py [-h] [-g GREETING] name

positional arguments:
  name                  name of user

optional arguments:
  -h, --help            show this help message and exit
  -g GREETING, --greeting GREETING
                        optional alternate greeting
$ python hello.py world
Hello, world!
$ python hello.py John -g Howdy
Howdy, John!

Para más detalles por favor lea la documentación argparse .

Ejemplo básico con docopt.

docopt convierte el argumento de la línea de comando analizando en su cabeza. En lugar de analizar los argumentos, simplemente escriba la cadena de uso para su programa, y ​​docopt analiza la cadena de uso y la utiliza para extraer los argumentos de la línea de comandos.

"""
Usage:
    script_name.py [-a] [-b] <path>

Options:
    -a            Print all the things.
    -b            Get more bees into the path.
"""
from docopt import docopt


if __name__ == "__main__":
    args = docopt(__doc__)
    import pprint; pprint.pprint(args)

Ejecuciones de muestra:

$ python script_name.py
Usage:
    script_name.py [-a] [-b] <path>
$ python script_name.py something
{'-a': False,
 '-b': False,
 '<path>': 'something'}
$ python script_name.py something -a
{'-a': True,
 '-b': False,
 '<path>': 'something'}
$ python script_name.py -b something -a
{'-a': True,
 '-b': True,
 '<path>': 'something'}

Estableciendo argumentos mutuamente excluyentes con argparse

Si quieres que dos o más argumentos sean mutuamente excluyentes. Puede utilizar la función argparse.ArgumentParser.add_mutually_exclusive_group() . En el siguiente ejemplo, pueden existir foo o bar, pero no ambos al mismo tiempo.

import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument("-f", "--foo")
group.add_argument("-b", "--bar")
args = parser.parse_args()
print "foo = ", args.foo
print "bar = ", args.bar

Si intenta ejecutar el script especificando los argumentos --foo y --bar , el script se quejará con el mensaje a continuación.

error: argument -b/--bar: not allowed with argument -f/--foo

Usando argumentos de línea de comando con argv

Cada vez que se invoca un script de Python desde la línea de comandos, el usuario puede proporcionar argumentos de línea de comandos adicionales que se pasarán al script. Estos argumentos estarán disponibles para el programador de la variable del sistema sys.argv ( "argv" es un nombre tradicional utilizado en la mayoría de los lenguajes de programación, y significa "arg ument v ector").

Por convención, el primer elemento de la lista sys.argv es el nombre de la secuencia de comandos de Python, mientras que el resto de los elementos son los tokens que el usuario pasa al invocar la secuencia de comandos.

# cli.py
import sys
print(sys.argv)

$ python cli.py
=> ['cli.py']

$ python cli.py fizz
=> ['cli.py', 'fizz']

$ python cli.py fizz buzz
=> ['cli.py', 'fizz', 'buzz']

Aquí hay otro ejemplo de cómo usar argv . Primero eliminamos el elemento inicial de sys.argv porque contiene el nombre del script. Luego combinamos el resto de los argumentos en una sola oración, y finalmente imprimimos esa oración antes del nombre del usuario que ha iniciado sesión (para que emule un programa de chat).

import getpass
import sys

words = sys.argv[1:]
sentence = " ".join(words)
print("[%s] %s" % (getpass.getuser(), sentence))

El algoritmo comúnmente utilizado cuando se analiza "manualmente" un número de argumentos no posicionales es iterar sobre la lista sys.argv . Una forma es repasar la lista y resaltar cada elemento de la misma:

# reverse and copy sys.argv
argv = reversed(sys.argv)
# extract the first element
arg = argv.pop()
# stop iterating when there's no more args to pop()
while len(argv) > 0:
    if arg in ('-f', '--foo'):
        print('seen foo!')
    elif arg in ('-b', '--bar'):
        print('seen bar!')
    elif arg in ('-a', '--with-arg'):
        arg = arg.pop()
        print('seen value: {}'.format(arg))
    # get the next value
    arg = argv.pop()

Mensaje de error del analizador personalizado con argparse

Puede crear mensajes de error del analizador de acuerdo con las necesidades de su script. Esto es a través de la función argparse.ArgumentParser.error . El siguiente ejemplo muestra la secuencia de comandos imprimiendo un uso y un mensaje de error a stderr cuando se --foo pero no --bar .

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-f", "--foo")
parser.add_argument("-b", "--bar")
args = parser.parse_args()
if args.foo and args.bar is None:
    parser.error("--foo requires --bar. You did not specify bar.")

print "foo =", args.foo
print "bar =", args.bar

Asumiendo que el nombre de su script es sample.py, y ejecutamos: python sample.py --foo ds_in_fridge

El guión se quejará con lo siguiente:

usage: sample.py [-h] [-f FOO] [-b BAR]
sample.py: error: --foo requires --bar. You did not specify bar.

Agrupación conceptual de argumentos con argparse.add_argument_group ()

Cuando crea un argparse ArgumentParser () y ejecuta su programa con '-h', recibe un mensaje de uso automático que explica con qué argumentos puede ejecutar su software. De forma predeterminada, los argumentos posicionales y los argumentos condicionales están separados en dos categorías, por ejemplo, aquí hay un pequeño script (example.py) y el resultado cuando ejecuta python example.py -h .

import argparse

parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
parser.add_argument('--bar_this')
parser.add_argument('--bar_that')
parser.add_argument('--foo_this')
parser.add_argument('--foo_that')
args = parser.parse_args()
usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
                        [--foo_this FOO_THIS] [--foo_that FOO_THAT]
                        name

Simple example

positional arguments:
  name                 Who to greet

optional arguments:
  -h, --help           show this help message and exit
  --bar_this BAR_THIS
  --bar_that BAR_THAT
  --foo_this FOO_THIS
  --foo_that FOO_THAT

Hay algunas situaciones en las que desea separar sus argumentos en secciones conceptuales adicionales para ayudar a su usuario. Por ejemplo, es posible que desee tener todas las opciones de entrada en un grupo y todas las opciones de formato de salida en otro. El ejemplo anterior se puede ajustar para separar los --foo_* de los --bar_* así.

import argparse

parser = argparse.ArgumentParser(description='Simple example')
parser.add_argument('name', help='Who to greet', default='World')
# Create two argument groups
foo_group = parser.add_argument_group(title='Foo options')
bar_group = parser.add_argument_group(title='Bar options')
# Add arguments to those groups
foo_group.add_argument('--bar_this')
foo_group.add_argument('--bar_that')
bar_group.add_argument('--foo_this')
bar_group.add_argument('--foo_that')
args = parser.parse_args()

Que produce esta salida cuando se ejecuta python example.py -h :

usage: example.py [-h] [--bar_this BAR_THIS] [--bar_that BAR_THAT]
                        [--foo_this FOO_THIS] [--foo_that FOO_THAT]
                        name

Simple example

positional arguments:
  name                 Who to greet

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

Foo options:
  --bar_this BAR_THIS
  --bar_that BAR_THAT

Bar options:
  --foo_this FOO_THIS
  --foo_that FOO_THAT

Ejemplo avanzado con docopt y docopt_dispatch

Al igual que con docopt, con [docopt_dispatch] creas tu --help en la variable __doc__ de tu módulo de punto de entrada. Allí, se llama dispatch con la cadena doc como argumento, para que pueda ejecutar el analizador sobre él.

Una vez hecho esto, en lugar de manejar manualmente los argumentos (que por lo general terminan en una estructura ciclomática alta de / else), lo dejas para enviar, dando solo la forma en que quieres manejar el conjunto de argumentos.

Esto es para lo que es el decorador dispatch.on : le da el argumento o la secuencia de argumentos que deberían desencadenar la función, y esa función se ejecutará con los valores coincidentes como parámetros.

"""Run something in development or production mode.

Usage: run.py --development <host> <port>
       run.py --production <host> <port>
       run.py items add <item>
       run.py items delete <item>

"""
from docopt_dispatch import dispatch

@dispatch.on('--development')
def development(host, port, **kwargs):
    print('in *development* mode')

@dispatch.on('--production')
def development(host, port, **kwargs):
    print('in *production* mode')

@dispatch.on('items', 'add')
def items_add(item, **kwargs):
    print('adding item...')

@dispatch.on('items', 'delete')
def items_delete(item, **kwargs):
    print('deleting item...')

if __name__ == '__main__':
    dispatch(__doc__)


Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow