2010-11-06 21 views
8

Estoy escribiendo un servidor de herramienta de consulta, y tengo un poco de código para analizar los argumentos en la parte superior:Python argparse: nargs + o * según el argumento antes

# Parse arguments 
p = argparse.ArgumentParser() 
g = p.add_mutually_exclusive_group(required=True) 
g.add_argument('--odam', dest='query_type', action='store_const', 
     const='odam', help="Odamex Master query.") 
g.add_argument('--odas', dest='query_type', action='store_const', 
     const='odas', help="Odamex Server query.") 
p.add_argument('address', nargs='*') 
args = p.parse_args() 

# Default master server arguments. 
if args.query_type == 'odam' and not args.address: 
    args.address = [ 
      'master1.odamex.net:15000', 
      'master2.odamex.net:15000', 
      ] 

# If we don't have any addresses by now, we can't go on. 
if not args.address: 
    print "If you are making a server query, you must pass an address." 
    sys.exit(1) 

¿Hay una mejor forma de hacer esto, preferiblemente todo dentro del analizador? Ese último error parece un poco fuera de lugar, y sería bueno si pudiera hacer nargs para la dirección dependiendo de si --odam o --- odas se pasa. Podría crear un subparser, pero eso haría que la ayuda se vea un poco extraña ya que dejaría fuera de las direcciones parte del comando.

Respuesta

12

Usted puede hacer esto con una costumbre argparse.Action:

import argparse 
import sys 

class AddressAction(argparse.Action): 
    def __call__(self, parser, args, values, option = None): 
     args.address=values 
     if args.query_type=='odam' and not args.address: 
      args.address=[ 
       'master1.odamex.net:15000', 
       'master2.odamex.net:15000', 
       ]   
     if not args.address: 
      parser.error("If you are making a server query, you must pass an address.") 

p = argparse.ArgumentParser() 
g = p.add_mutually_exclusive_group(required=True) 
g.add_argument('--odam', dest='query_type', action='store_const', 
     const='odam', help="Odamex Master query.") 
g.add_argument('--odas', dest='query_type', action='store_const', 
     const='odas', help="Odamex Server query.") 
p.add_argument('address', nargs='*', action=AddressAction) 
args = p.parse_args() 

produce

% test.py --odas 
If you are making a server query, you must pass an address. 
% test.py --odam 
Namespace(address=['master1.odamex.net:15000', 'master2.odamex.net:15000'], query_type='odam') 
% test.py --odam 1 2 3 
Namespace(address=['1', '2', '3'], query_type='odam') 
+0

precisamente lo que estaba buscando! – AlexMax

+0

Probablemente tenga más sentido usar [error de analizador] (http://docs.python.org/library/argparse.html#argparse.ArgumentParser.error) en lugar de 'sys.exit()' – Christoph

+0

@Christoph: True; ¡Gracias! – unutbu

Cuestiones relacionadas