2011-03-10 46 views
9

我想有一個參數,我的程序,有一些可選的參數以及一些必要的參數。事情是這樣的:的Python argparse可選的分論點

[--print text [color [size]] 

,所以你可以通過它的部分包括:

mycommand --print hello 
mycommand --print hello blue 
mycommand --print hello red 12 

可能有多個,這些所以它是一個單一的add_argument。例如:

[--print text [color]] [--output filename [overwrite]] 

我能做到這一點接近我想要什麼樣的參數:

>>> parser = argparse.ArgumentParser() 
>>> act = parser.add_argument('--foo', nargs=3, metavar=('x','y','z')) 
>>> act = parser.add_argument('--bar', nargs='?') 
>>> act = parser.add_argument('--baz', nargs='*') 
>>> parser.print_help() 
usage: [-h] [--foo x y z] [--bar [BAR]] [--baz [BAZ [BAZ ...]]] 

optional arguments: 
    -h, --help   show this help message and exit 
    --foo x y z 
    --bar [BAR] 
    --baz [BAZ [BAZ ...]] 

但並不完全。有沒有辦法用argparse來做到這一點?我知道我可以將它們全部製作成nargs="*",但是--help不會列出可選參數的名稱。如果我通過nargs="*"和metavar的元組,argparse會拋出異常。

回答

5

閱讀source code(從take_action開始),我相信你想要的是不可能的。所有參數解析和傳遞到動作是基於nargs完成的,而nargs是數字OPTIONAL(「?」),ZERO_OR_MORE(「*」),ONE_OR_MORE(「+」),PARSERREMAINDER。這必須是確定的行動對象(句柄輸入)甚至認爲它是越來越之前,所以它不能動態地計算出nargs

我認爲你需要忍受一個解決辦法。我想也許有--foo-x x--foo-y y--foo-z z,或許也是--foo x y z

+1

感謝。這太糟糕了。 – jterrace 2011-03-11 03:44:33

7

如何

def printText(args): 
    print args 

parser = argparse.ArgumentParser() 
subparser = parser.add_subparsers() 
printer = subparser.add_parser('print') 
printer.add_argument('text') 
printer.add_argument('color', nargs='?') 
printer.add_argument('size', type=int, nargs='?') 
printer.set_defaults(func=printText) 

cmd = parser.parse_args() 
cmd.func(cmd) 

然後你得到這樣的事情:

$ ./test.py -h 
usage: test.py [-h] {print} ... 

positional arguments: 
    {print} 

$ ./test.py print -h 
usage: test.py print [-h] text [color] [size] 

positional arguments: 
    text 
    color 
    size 

$ ./test.py print text 
Namespace(color=None, func=<function printText at 0x2a96150b90>, size=None, text='text') 

$ ./test.py print text red 
Namespace(color='red', func=<function printText at 0x2a96150b90>, size=None, text='text') 

$ ./test.py print text red 12 
Namespace(color='red', func=<function printText at 0x2a96150b90>, size=12, text='text') 
+0

但是,您只能一次指定一個子分析器,這樣做是否適用於多個分析器。 – jterrace 2011-12-14 15:07:58

+0

你可以舉一個多個例子嗎?我的例子歸結爲可選的位置參數,它們都是nargs ='?',所以取決於你需要做什麼,它可以在沒有子分析器的情況下完成。或多個subparsers .. :) – CNeo 2011-12-16 15:36:18

+0

我在我的OP的例子:我的命令 - 打印你好紅12 - 輸出文件名覆蓋 – jterrace 2011-12-16 16:55:16

0

,將單ARG工作:

parser.add_argument('--write_google', nargs='?', const='Yes', 
        choices=['force', 'Yes'], 
        help="write local changes to google") 
1

根據德文Jeanpierre的答案,似乎使用'+'(一個或多個)而不是'*'會做你想要達到的目標。 (PS:我剛剛在他的回答評論,如果我有足夠的點數)

+0

不要忘記 - 他也不想有超過三個參數。如果你將這個內容加入到你的文章中,那麼你可以發表一個獨立的答案(當然,如果你認爲讓皮埃爾的想法。) – Alex 2017-08-22 16:15:49