2012-02-22 15 views
57

Sto provando a passare una lista di argomenti a uno script python usando la libreria argh. Qualcosa che può prendere gli ingressi come questi:python argh/argparse: come posso passare un elenco come argomento della riga di comando?

./my_script.py my-func --argA blah --argB 1 2 3 4 
./my_script.py my-func --argA blah --argB 1 
./my_script.py my-func --argA blah --argB 

Il mio codice interno è simile al seguente:

import argh 

@argh.arg('--argA', default="bleh", help='My first arg') 
@argh.arg('--argB', default=[], help='A list-type arg--except it\'s not!') 
def my_func(args): 
    "A function that does something" 

    print args.argA 
    print args.argB 

    for b in args.argB: 
     print int(b)*int(b) #Print the square of each number in the list 
    print sum([int(b) for b in args.argB]) #Print the sum of the list 

p = argh.ArghParser() 
p.add_commands([my_func]) 
p.dispatch() 

Ed ecco come si comporta:

$ python temp.py my-func --argA blooh --argB 1 
blooh 
['1'] 
1 
1 

$ python temp.py my-func --argA blooh --argB 10 
blooh 
['1', '0'] 
1 
0 
1 

$ python temp.py my-func --argA blooh --argB 1 2 3 
usage: temp.py [-h] {my-func} ... 
temp.py: error: unrecognized arguments: 2 3 

Il problema sembra abbastanza semplice: Argh è accettando solo il primo argomento e trattandolo come una stringa. Come faccio a "aspettarmi" invece una lista di numeri interi?

Vedo how this is done in optparse, ma per quanto riguarda l'argparse (non deprecato)? O usando la sintassi molto più decorata di argh? Questi sembrano molto più pitonici.

risposta

76

Con argparse, è sufficiente utilizzare type=int

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('-a', '--arg', nargs='+', type=int) 
print parser.parse_args() 

uscita Esempio:

$ python test.py -a 1 2 3 
Namespace(arg=[1, 2, 3]) 

Edit: io non sono a conoscenza argh, ma sembra essere solo un wrapper argparse e questo ha funzionato per me:

import argh 

@argh.arg('-a', '--arg', nargs='+', type=int) 
def main(args): 
    print args 

parser = argh.ArghParser() 
parser.add_commands([main]) 
parser.dispatch() 

Esempio di output:

$ python test.py main -a 1 2 3 
Namespace(arg=[1, 2, 3], function=<function main at 0x.......>) 
+1

Impressionante! Ho ottimizzato il codice per includere la riga: @ argh.arg ('- argB', default = [], help = 'Un argomento di tipo lista - tranne che non \! S!', Nargs = '+', type = int) e argh è piaciuto. Grazie per l'aiuto! – Abe

+0

Sì, questo è il modo corretto. Le versioni recenti di Argh supportano anche la notazione "naturale", più pitonica: 'func (argA, * argB)' (anche se '* args' esegue il mapping a' nargs = '*' 'invece di' nargs = '+' ') . –

+0

@jcollado: vedo che quando uso nargs =, non posso fare -a = 1 2 3. Quello che voglio dire è usare '=' dopo l'argomento metavar. Qualsiasi soluzione per lasciarmi usare = per ogni argomento. Per esempio nel tuo esempio, voglio fare, python test.py main -a = 1 2 3 –

1

Per poter accedere a ciascun valore di parametro, il seguente codice può essere utile.

import argparse 
parser = argparse.ArgumentParser() 
parser.add_argument('-a', '--arg', nargs='+', type=int) 
args = vars(parser.parse_args()) 

print "first parameter:" + str(args["arg"][0]) 
print "second parameter:" + str(args["arg"][1]) 
print "third parameter:" + str(args["arg"][2]) 
Problemi correlati