2015-06-07 22 views
6
parser = argparse.ArgumentParser() 
parser.add_argument("-p", "--pattern", help="Pattern file") 
args = parser.parse_args() 

現在是否有可能從args找回字符串"--pattern"? 我需要的字符串,以便我可以構造一個cmd列表傳遞給Popen喜歡Popen(['some_other_program', args.pattern.option_string, args.pattern], ...)沒有重複它(並不得不保持在兩個地方)(Popen(['some_other_prog', '--pattern', args.pattern], ...))。如何使用argparse取回選項字符串?

我需要爲另一個程序創建一個包裝。有些參數需要傳遞給包裝程序(通過Popen),有些則是包裝需要的。


是否有更好的方法比下面的例子?

pass_1 = '--to-be-passed' 
parser = argparse.ArgumentParser() 
parser.add_argument("-p", pass_1, help="Pass me on") 
parser.add_argument("-k", "--arg-for-wrapper") 
args = parser.parse_args() 

... 
process = Popen(['wrapped_program', pass_1, args.pass_1], ...) 
... 

保持ARGS變量的這種方法不是非常好,因爲:

  1. 保持短選項長選項一起變得困難。
  2. Popen如果在另一個函數中調用,則需要將這些變量(或它們的字典)傳遞給該函數。這似乎是多餘的,因爲args傳遞給它應該是足夠的。
+1

你爲什麼不只是將其存儲在一個變量? ''pattern_str ='--pattern''',然後是''..add_argument(... pattern_str ...)''。那裏 - 只有一個維修點。 –

+0

這聽起來像你試圖硬編碼兩個單獨程序之間的依賴關係(並且不靈活,因此:「這些程序必須共享選項名稱」)。那真的是你想要做的嗎? – Hurkyl

+0

@Hyrkyl是的,python程序是另一個程序的包裝。 – user80551

回答

2

添加destadd_argument電話。

parser.add_argmument("p", "--pattern", dest="pattern", help="your help text") 
args = parser.parse_args() 
args = vars(args) 

您可以參考args["pattern"]的模式。

+2

'argparse'從'--pattern'中推斷dest是'pattern'。所以添加的'dest'是沒有必要的。 'args'是一個名字空間對象,不是字典。 'vars(args)'從中產生一本字典。 – hpaulj

1

被刪除的答案和評論表明對於你想要的東西存在一些混淆。所以我會加入混亂。

正常情況下,解析器不記錄選項字符串。但它提供給Action__call__方法。所以一個自定義的Action類可以保存它。 argparse文檔中的FooAction自定義類示例說明了這一點。

如果我定義這個動作的子類:

In [322]: p.parse_args('-p test -o teseting'.split()) 
Out[322]: Namespace(other=['teseting', '-o'], pass_me_on='test') 

In [323]: p.parse_args('-p test --other teseting'.split()) 
Out[323]: Namespace(other=['teseting', '--other'], pass_me_on='test') 

顯然option_string:

​​

選項字符串與值( '-o' 或 ' - 其他')一起記錄並且可以以不同的順序,字典中的值,作爲命名空間中的單獨屬性等來記錄值。


還有其他方法可以將選項傳遞給另一個程序,特別是如果包裝解析器不需要自己處理它們時。

​​從sys.argv[1:]獲取參數,但不會更改它。所以即使你的解析器使用了一些參數,你也可以將這個列表傳遞給popen(全部或部分)。

argparse docs有一個例子,在nargs=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') 

所以,你可以調用popen喜歡的東西

plist = ['wrapped_program'] 
plist.extend(args.args) 
popen(plist, ...) 

使用parse.parse_known_args也可用於收集非解析的話爲「演員名單。文檔的這一部分討論將這些字符串傳遞給另一個程序(就像你正在做的那樣)。與REMAINDER情況相反,額外的東西不一定是最後一個。

這些工作,當然,只有當這個解析器本身不需要--pattern。如果解析它,則它不會出現在REMAINDER或extras中。在這種情況下,你將不得不重新添加到您給popen

名單我會調整從而解析器:

pass_1 = 'passed' # without the -- or internal - 
dpass_` = '--'+pass_ 
parser = argparse.ArgumentParser() 
parser.add_argument("-p", dpass_1, help="Pass me on") 
parser.add_argument("-k", "--arg-for-wrapper") 
args = parser.parse_args() 
process = Popen(['wrapped_program', dpass_1, getattr(args, pass_1)], ...) 

另一種選擇:

parser = argparse.ArgumentParser() 
pass_action = parser.add_argument("-p", '--pass-me-on', help="Pass me on") 
parser.add_argument("-k", "--arg-for-wrapper") 
args = parser.parse_args() 

如果打印pass_action(在一個外殼)你會得到這樣的東西:

_StoreAction(option_strings=['-p', '--pass-me-on'], dest='pass_me_on', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None) 

所以你c烏爾德拉--namedest從該對象,即:

process = Popen(['wrapped_program', pass_action.option_strings[-1], getattr(args, pass_action.dest), ...], ...) 

你要看看在sys.argv看到使用了哪個option_string(長,短或其他)。解析器不會在任何地方記錄。

注意' - 通過我'生產dest='pass_me_on'。將-轉換爲_可能會導致從另一個字符串導出一個字符串變得複雜。

如果您有dest字符串,則必須使用getattr將其從args命名空間中拉出,或使用vars(args)[dest](字典訪問)。

另一個問題。如果--pattennargs='+', its value will be a list, as opposed to a string. You'd have to careful when merging that into the popen`參數列表。

0

似乎有沒有一種簡單的方法來獲得從parser.parse_args()的結果原來選項字符串,但你可以從parser對象獲得它們。您只需要查看其__dict__,以便在創建後檢索parser設置。在你的情況下,你需要_option_string_actions字段。不幸的是,這似乎沒有得到正式支持,因爲我找不到專門用於此目的的ArgumentParser方法,所以YMMV。關於Python 3:

演示:

parser = argparse.ArgumentParser() 
parser.add_argument('--foo', '-f', type=int, default=1000, help='intensity of bar') 
parser.add_argument('--bar', '-b', type=str, default='bla', help='whatever') 
store_action_dict=vars(parser)['_option_string_actions'] 
print(store_action_dict.keys()) # dict_keys(['--help', '-b', '-f', '-h', '--foo', '--bar']) 
相關問題