2012-02-22 19 views
57

Próbuję przekazać listę argumentów do skryptu Pythona przy użyciu biblioteki argh. Coś, co może wejść, takie jak:python argh/argparse: Jak mogę przekazać listę jako argument wiersza poleceń?

./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 

Mój wewnętrzny kod wygląda następująco:

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

A oto jak się zachowuje:

$ 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 

Problem wydaje się dość prosta: argh jest akceptuje tylko pierwszy argument i traktuje go jako ciąg znaków. Jak mogę "oczekiwać" listy liczb całkowitych?

Widzę how this is done in optparse, ale co z (nie-przestarzałym) argparse? Lub używając znacznie ładniej udekorowanej składni argha? Te wydają się znacznie bardziej pythonic.

Odpowiedz

76

Z argparse, wystarczy użyć type=int

import argparse 

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

Przykâadowa:

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

Edycja: nie jestem zaznajomiony z argh, ale wydaje się być po prostu otoki wokół argparse i to pracował dla mnie:

import argh 

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

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

Przykład Wydajność:

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

Awesome! Poprawiłem kod, dodając linię: @ argh.arg ('- argB', default = [], help = 'Argument typu listy - z tym że nie jest!', Nargs = '+', type = int) i argh polubili to. Dzięki za pomoc! – Abe

+0

Tak, to jest poprawna metoda. Najnowsze wersje Argh również obsługują "naturalną", bardziej pytonową notację: 'func (argA, * argB)' (chociaż '* args' mapuje na' nargs = '*' 'zamiast' nargs = '+' ') . –

+0

@jcollado: Widzę, że kiedy używam nargs =, nie mogę zrobić -a = 1 2 3. Mam na myśli to, że używam "=" po argumencie metavar. Każde rozwiązanie pozwalające mi używać = dla każdego argumentu. Na przykład w twoim przykładzie chcę, python test.py main -a = 1 2 3 –

1

że aby mieć dostęp do każdego parametru następujące kod może być pomocny.

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]) 
Powiązane problemy