2017-07-17 77 views
0

我正在編寫一個程序,該程序允許用戶通過參數指定要加載的模塊(然後用於執行操作)。我試圖設置一種輕鬆地將參數傳遞給這個內部模塊的方法,並且我試圖使用ArgParse的action='append'讓它構建一個我將通過的參數列表。配置argparse以接受帶引號的參數

這裏的參數的基本佈局,我使用

parser.add_argument('-M', '--module', 
        help="Module to run on changed files - should be in format MODULE:CLASS\n\ 
          Specified class must have function with the signature run(src, dest)\ 
          and return 0 upon success", 
        required=True) 
parser.add_argument('-A', '--module_args', 
        help="Arg to be passed through to the specified module", 
        action='append', 
        default=[]) 

但是 - 如果我再嘗試用python my_program -M module:class -A "-f filename"運行這個程序(在這裏我想通過-f filename傳遞給我的模塊),它似乎解析-f作爲自己的參數(和我得到的錯誤my_program: error: argument -A/--module_args: expected one argument

任何想法

+1

看看'sys.argv'。引號是通過解析器還是被shell所吞噬? – hpaulj

回答

1

有了:

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('-M', '--module', 
        help="Module to run on changed files - should be in format MODULE:CLASS\n\ 
          Specified class must have function with the signature run(src, dest)\ 
          and return 0 upon success", 
        ) 
parser.add_argument('-A', '--module_args', 
        help="Arg to be passed through to the specified module", 
        action='append', 
        default=[]) 
import sys 
print(sys.argv) 
print(parser.parse_args()) 

我得到:

1028:~/mypy$ python stack45146728.py -M module:class -A "-f filename" 
['stack45146728.py', '-M', 'module:class', '-A', '-f filename'] 
Namespace(module='module:class', module_args=['-f filename']) 

這是使用Linux Shell 。引用的字符串保留一個字符串,如sys.argv所示,並且被正確解釋爲-A的參數。

沒有引號,-f是單獨的並且被解釋爲標誌。

1028:~/mypy$ python stack45146728.py -M module:class -A -f filename 
['stack45146728.py', '-M', 'module:class', '-A', '-f', 'filename'] 
usage: stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS] 
stack45146728.py: error: argument -A/--module_args: expected one argument 

您是否使用windows或一些其他OS /外殼,不處理引號以同樣的方式?


Argparse `append` not working as expected

你一個稍微不同的命令行問:

1032:~/mypy$ python stack45146728.py -A "-k filepath" -A "-t" 
['stack45146728.py', '-A', '-k filepath', '-A', '-t'] 
usage: stack45146728.py [-h] [-M MODULE] [-A MODULE_ARGS] 
stack45146728.py: error: argument -A/--module_args: expected one argument 

正如我已經指出-k filepath通過爲一個字符串傳遞。由於空間的原因,​​不會將其解釋爲標誌。但它確實將這個光禿禿的'-t'解釋爲一面旗幟。

關於將未定義的'-xxx'字符串解釋爲參數而不是標記的可能性有一個錯誤/問題。我不得不看看是否有任何東西進入生產。

有關如何將字符串分類爲標誌或參數的詳細信息,請參見argparse.ArgumentParser._parse_optional方法。它包含註釋:

# if it contains a space, it was meant to be a positional 
    if ' ' in arg_string: 
     return None 

http://bugs.python.org/issue9334argparse does not accept options taking arguments beginning with dash (regression from optparse)是對話題的老長的bug /問題。

+0

感謝(交叉問題)答案!它似乎只是用一個空格填充這些引用的參數,並試圖指導我的用戶有關此解決方法現在必須執行的操作 – wKavey

0

解決的辦法是接受任意參數 - ?有在示例argparse's doc here

argparse.REMAINDER。所有其餘的命令行參數都被收集到一個列表中。這是可分派給其他命令行實用程序的命令行工具中很常用:

>>> parser = argparse.ArgumentParser(prog='PROG') 
>>> parser.add_argument('--foo') 
>>> parser.add_argument('command') 
>>> parser.add_argument('args', nargs=argparse.REMAINDER) 
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split())) 
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B') 
+0

這是一個有趣的解決方案 - 但是我相信它會更好(至少對我的應用程序來說)不接受任意的命令參數。至少用填充空格的解決方法,用戶仍然必須有意使用'-A'參數 – wKavey