python ejemplo - ¿Cómo usar los subparsores argparse correctamente?




boolean action (2)

He estado buscando en todos los ejemplos del subparser aquí y en general, pero parece que no me resulta fácil darme cuenta de esto.

Tengo dos tipos de var, uno de los cuales tiene restricciones, así que pensé que el subparser era el camino a seguir. por ejemplo, "t" permite "A" o "B". Si el usuario aprueba "A", se le solicitará que especifique si es "a1" o "a2". Si pasan solo "B", entonces nada.

¿Puedo hacer esto y que argparse me devuelva qué tipo de "A" pasó o si solo era "B"?

Lo siguiente parece funcionar, pero por alguna razón se rompe al pasar cualquier cosa después de la sub-distribución.

por ejemplo, desde un terminal de Linux

>> python test01.py -t A a1 -v 61

errores con ...

usage: test01.py a1 [-h]
test01.py a1: error: unrecognized arguments: -v

Espero que tenga sentido.

El código:

import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='types of A')

parser.add_argument("-t",
                    choices = ["A", "B"],
                    dest = "type",
                    required=True,
                    action='store',
                    help="Some help blah blah")

cam_parser = subparsers.add_parser('a1', help='Default')
cam_parser.set_defaults(which='a1')

cam_parser = subparsers.add_parser('a2', help='parse this instead of default')
cam_parser.set_defaults(which='a2')


parser.add_argument("-v",
                    nargs = '+',
                    required=True,
                    dest = "version",
                    type=int,
                    action='store',
                    help="some version help blah blah")   

argument = parser.parse_args()

print argument.type
print argument.version

Answers

Los subparsers se invocan en función del valor del primer argumento posicional , por lo que su llamada se vería como

python test01.py A a1 -v 61

La "A" activa el subparser apropiado, que se definiría para permitir un argumento posicional y la opción -v .

Porque argparse no impone ninguna restricción sobre el orden en el que pueden aparecer argumentos y opciones, y no hay una forma simple de modificar qué argumentos / opciones pueden aparecer una vez que el análisis ha comenzado (algo que involucre acciones personalizadas que modifiquen la instancia del analizador podría funcionar) , deberías considerar reemplazar -t mismo:

import argparse

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(help='types of A')
parser.add_argument("-v", ...)

a_parser = subparsers.add_parser("A")
b_parser = subparsers.add_parser("B")

a_parser.add_argument("something", choices=['a1', 'a2'])

Como -v se define para el analizador principal, se debe especificar antes del argumento que especifica qué subparser se utiliza para los argumentos restantes.


Aquí hay un ejemplo simple de encadenar decoradores. Observe la última línea: muestra lo que está pasando debajo de las cubiertas.

############################################################
#
#    decorators
#
############################################################

def bold(fn):
    def decorate():
        # surround with bold tags before calling original function
        return "<b>" + fn() + "</b>"
    return decorate


def uk(fn):
    def decorate():
        # swap month and day
        fields = fn().split('/')
        date = fields[1] + "/" + fields[0] + "/" + fields[2]
        return date
    return decorate

import datetime
def getDate():
    now = datetime.datetime.now()
    return "%d/%d/%d" % (now.day, now.month, now.year)

@bold
def getBoldDate(): 
    return getDate()

@uk
def getUkDate():
    return getDate()

@bold
@uk
def getBoldUkDate():
    return getDate()


print getDate()
print getBoldDate()
print getUkDate()
print getBoldUkDate()
# what is happening under the covers
print bold(uk(getDate))()

La salida se ve como:

17/6/2013
<b>17/6/2013</b>
6/17/2013
<b>6/17/2013</b>
<b>6/17/2013</b>






python argparse