2010-11-06 15 views
8

J'écris un outil Interrogation du serveur, et j'ai un peu de code pour analyser les arguments au sommet:Python argparse: nargs + ou * selon l'argument avant

# 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) 

Y at-il une plus belle façon de le faire, de préférence tout dans l'analyseur? Cette dernière erreur semble un peu hors de propos, et ce serait bien si je pouvais faire dépendre les nargs de l'adresse si --odam ou --- odas est passé. Je pourrais créer un sous-parent, mais cela rendrait l'aide un peu bizarre, car cela laisserait la partie des adresses de la commande.

Répondre

12

Vous pouvez le faire avec une coutume 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() 

cède

% 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

Précisément ce que je cherchais! – AlexMax

+0

Il est probablement plus logique d'utiliser [erreur d'analyse] (http://docs.python.org/library/argparse.html#argparse.ArgumentParser.error) au lieu de 'sys.exit()' – Christoph

+0

@Christoph: True; Merci! – unutbu