2012-02-22 2 views
57

Я пытаюсь передать список аргументов скрипту python, используя библиотеку argh. То, что может принимать входные сигналы, подобные этим:python argh/argparse: Как передать список в качестве аргумента командной строки?

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

Мой внутренний код выглядит следующим образом:

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

А вот как он себя ведет:

$ 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 

Проблема кажется довольно проста: Argh является только принимая первый аргумент и рассматривая его как строку. Как мне заставить «ожидать» список целых чисел?

Я вижу how this is done in optparse, но как насчет (не-устаревшего) argparse? Или используя гораздо более красиво оформленный синтаксис argh? Они кажутся гораздо более питоническими.

ответ

76

С argparse, вы просто использовать type=int

import argparse 

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

Пример вывода:

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

Edit: Я не знаком с argh, но это, кажется, просто оберткой argparse и это работал для меня:

import argh 

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

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

Пример вывода:

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

Удивительный! Я изменил код, чтобы включить строку: @ argh.arg ('- argB', default = [], help = 'Аргумент типа списка, за исключением его не!', Nargs = '+', type = int) и argh понравилось. Спасибо за помощь! – Abe

+0

Да, это правильный путь. Недавние версии Argh также поддерживают «естественную», более питоновскую нотацию: «func (argA, * argB)» (хотя '* args' отображает' nargs = '*' 'вместо' nargs = '+' ') , –

+0

@jcollado: Я вижу, что когда я использую nargs =, я не могу сделать -a = 1 2 3. Я имею в виду, что использование '=' после метавара аргумента. Любое решение, позволяющее мне использовать = для каждого аргумента. Для примера в вашем примере я хочу сделать, python test.py main -a = 1 2 3 –

1

Для доступа к каждому значению параметра я могу получить следующий код.

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