[英]How do you convert command line args in python to a dictionary?
我正在編寫一個帶有任意命令行參數的應用程序,然后將它們傳遞給python函數:
$ myscript.py --arg1=1 --arg2=foobar --arg1=4
然后在myscript.py里面:
import sys
argsdict = some_function(sys.argv)
其中argsdict
看起來像這樣:
{'arg1': ['1', '4'], 'arg2': 'foobar'}
我確定某個地方有一個圖書館可以做到這一點,但我找不到任何東西。
編輯: argparse / getopt / optparse不是我想要的。 這些庫用於定義每次調用相同的接口。 我需要能夠處理任意參數。
除非,argparse / optparse / getopt具有執行此操作的功能......
..我可以問你為什么要重寫(一堆)輪子,當你有:
?
編輯:
在回復您的編輯時,optparse / argparse(后者僅在> = 2.7中可用)足夠靈活,可以擴展以滿足您的需求,同時保持一致的界面(例如,用戶希望能夠同時使用--arg=value
和--arg value
, -a value
和-avalue
等。使用預先存在的庫,您不必擔心支持所有這些語法等)。
這是使用argparse
的一個例子,雖然它是一個延伸。 我不會稱這個完整的解決方案,而是一個良好的開端。
class StoreInDict(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
d = getattr(namespace, self.dest)
for opt in values:
k,v = opt.split("=", 1)
k = k.lstrip("-")
if k in d:
d[k].append(v)
else:
d[k] = [v]
setattr(namespace, self.dest, d)
# Prevent argparse from trying to distinguish between positional arguments
# and optional arguments. Yes, it's a hack.
p = argparse.ArgumentParser( prefix_chars=' ' )
# Put all arguments in a single list, and process them with the custom action above,
# which convertes each "--key=value" argument to a "(key,value)" tuple and then
# merges it into the given dictionary.
p.add_argument("options", nargs="*", action=StoreInDict, default=dict())
args = p.parse_args("--arg1=1 --arg2=foo --arg1=4".split())
print args.options
你可以使用這樣的東西:
myscript.py
import sys
from collections import defaultdict
d=defaultdict(list)
for k, v in ((k.lstrip('-'), v) for k,v in (a.split('=') for a in sys.argv[1:])):
d[k].append(v)
print dict(d)
結果:
C:\>python myscript.py --arg1=1 --arg2=foobar --arg1=4
{'arg1': ['1', '4'], 'arg2': ['foobar']}
注意:值始終是一個列表,但我認為這更加一致。 如果你真的想要最終字典
{'arg1': ['1', '4'], 'arg2': 'foobar'}
然后你就可以跑了
for k in (k for k in d if len(d[k])==1):
d[k] = d[k][0]
然后。
像這樣的東西?
import sys
argsdict = {}
for farg in sys.argv:
if farg.startswith('--'):
(arg,val) = farg.split("=")
arg = arg[2:]
if arg in argsdict:
argsdict[arg].append(val)
else:
argsdict[arg] = [val]
與指定略有不同,值始終為列表。
這是我今天使用的,它解釋了:
--key=val
, --key
, -key
, -key val
def clean_arguments(args):
ret_args = defaultdict(list)
for index, k in enumerate(args):
if index < len(args) - 1:
a, b = k, args[index+1]
else:
a, b = k, None
new_key = None
# double hyphen, equals
if a.startswith('--') and '=' in a:
new_key, val = a.split('=')
# double hyphen, no equals
# single hyphen, no arg
elif (a.startswith('--') and '=' not in a) or \
(a.startswith('-') and (not b or b.startswith('-'))):
val = True
# single hypen, arg
elif a.startswith('-') and b and not b.startswith('-'):
val = b
else:
if (b is None) or (a == val):
continue
else:
raise ValueError('Unexpected argument pair: %s, %s' % (a, b))
# santize the key
key = (new_key or a).strip(' -')
ret_args[key].append(val)
return ret_args
或類似的東西)抱歉,如果這是愚蠢的,我是一個新手:)
$ python3 Test.py a 1 b 2 c 3
import sys
def somefunc():
keys = []
values = []
input_d = sys.argv[1:]
for i in range(0, len(input_d)-1, 2):
keys.append(input_d[i])
values.append(input_d[i+1])
d_sys = dict(zip(keys, values))
somefunc()
如果你真的想要自己編寫一些東西而不是一個合適的命令行解析庫,那么對於你的輸入,這應該是有用的:
dict(map(lambda x: x.lstrip('-').split('='),sys.argv[1:]))
你需要添加一些東西來捕獲參數,而不包含'='。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.