Pregunta

En la actualidad mi código es el siguiente. Me permite analizar múltiples parámetros de mi guión programa recibe. ¿Hay una manera diferente, que está más cerca de 'mejores prácticas'? No he visto el código de hecho utilizando la salida de argparse, sólo cómo configurarlo.

def useArguments():
    x = 0
    while x <= 5:
        if x == 0:                      
            if args.getweather != None:
                getWeather(args.getweather)
        if x == 1:
            if args.post != None:
                post(args.post)
        if x == 2:
            if args.custompost != None:
                custompost(args.custompost)
        if x == 3:
            if args.list != None:
                listAccounts(args.list)
        if x == 4:
            if args.add != None:
                addAccount(args.add[0])
        if x == 5:
            if args.edit != None:
                editAccount(args.edit[0])
        x = x + 1    


if __name__ == '__main__':

    updateConfig()

    parser = argparse.ArgumentParser(description='Post Yahoo weather to Twitter.', epilog="Report any bugs to example@email.com", prog='Program')

    parser.add_argument('-a', '--add', nargs=1, help='Add a new account. Use the desired account name as an argument.')
    parser.add_argument('-e', '--edit', nargs=1, choices=accountListSTR[:-1], help='Edit an account. Use the desired account name as an argument.')
    parser.add_argument('-g', '--getweather', nargs='*', choices=accountListSTR, help='Get weather and post here. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.')
    parser.add_argument('-p', '--post', nargs='*', choices=accountListSTR, help='Post weather to Twitter. Specify account(s) as argument. Use "all" for all accounts. If you specify multiple accounts, separate by a space NOT a comma.')
    parser.add_argument('-c', '--custompost', nargs=2, help='Post a custom message. Specify an account then type the message. Make sure you use "" around the message. Use "all" for all accounts.')
    parser.add_argument('-l', '--list', action='store_const', const='all', help='List all accounts.')
    parser.add_argument('--version', action='version', version='%(prog)s 0.3.3')

    args = parser.parse_args()

    useArguments()
¿Fue útil?

Solución

Se podría suministrar una costumbre acción para un argumento por, y yo cita:

  

pasar un objeto que implementa las   Acción API. La manera más fácil de hacer esto   es extender argparse.Action,   el suministro de una __call__ apropiado   método. El método debe __call__   aceptar cuatro parámetros:

     
      
  1. parser :. El objeto ArgumentParser que contiene esta acción
  2.   
  3. espacio de nombres : El objeto de espacio de nombres que será devuelto por parse_args(). La mayoría de las acciones de añadir un atributo a este objeto.
  4.   
  5. valores .. Los argumentos de línea de comandos asociados, con cualquier tipo conversiones aplicados (Tipo-conversiones se especifican con el tipo de palabra clave argumento para add_argument()
  6.   
  7. option_string : La cadena de opciones que se utiliza para invocar esta acción. El argumento option_string es opcional, y estará ausente si la acción está asociada con un argumento posicional.
  8.   

Otros consejos

http://docs.python.org/library/argparse.html # sub-comandos :

  

Una forma particularmente eficaz de manejar sub-comandos es combinar el uso del método add_subparsers() con llamadas a set_defaults() de modo que cada subparser sabe que la función Python que debería ejecutar.

En pocas palabras:

parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()

weather_parser = subparsers.add_parser('get-weather')
weather_parser.add_argument('--bar')
weather_parser.set_defaults(function=get_weather)  # !

args = parser.parse_args(['get-weather', '--bar', 'quux'])
print args.function(args)

A continuación, creamos un subparser para la get-weather de comandos y asignar la función get_weather a él.

Tenga en cuenta que la documentación dice que la palabra clave / atributo se denomina func pero definitivamente function como de argparse 1.1.

El código resultante es un poco demasiado prolijos por lo que he publicado un pequeño paquete "Argh" que hace las cosas más simples, por ejemplo:

parser = argparse.ArgumentParser()
add_commands(parser, [get_weather])
print dispatch(parser, ['get-weather', '--bar', 'quux'])

"Argh" puede hacer más, pero voy a dejar que desbordamiento de pila respuesta que. : -)

Con la excepción de --version, que es muy comúnmente una opción, las acciones que nos ha facilitado están mejor tratados como "subcomandos".

Estoy al tanto de los detalles argparse, ya que todavía tengo que probar Python 2.7, pero es posible echar un vistazo a la orden svn como ejemplo, aquí hay algo de pseudocódigo para la línea de comandos:

myprog [--version] <command> [<command opts>...]

Cuando <command> en:

add|edit|getweather|post|custompost|list

Y <command opts> son opciones específicas a ese comando. Usando optparse (que es similar), esto significaría que su comando sería devuelto en args, al llamar parse_args, que le permite hacer algo como esto:

opts, args = parser.parse_args()
if opts.version:
    ...
else:
    getattr("do_" + args[0])(*args[1:])

Me parece que este patrón particularmente útil para depurar, donde me proporcionan acceso a las funciones internas de la línea de comandos, y paso varios argumentos para probar. Ajuste la selección del controlador de comandos de acuerdo con su propio proyecto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top