如何将python中的命令行参数转换为字典?
我正在编写一个应用程序,它接受任意命令行参数,然后将它们传递给python函数:如何将python中的命令行参数转换为字典?,python,command-line,argv,sys,Python,Command Line,Argv,Sys,我正在编写一个应用程序,它接受任意命令行参数,然后将它们传递给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/geto
$ 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有这样做的功能…类似的功能
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]
与指定值稍有不同,该值始终是一个列表 如果您真的想编写自己的东西,而不是一个合适的命令行解析库,那么对于您的输入,这应该可以:
dict(map(lambda x: x.lstrip('-').split('='),sys.argv[1:]))
您需要添加一些内容来捕获参数,这些参数中没有“=”。您可以使用以下内容:
{'arg1': ['1', '4'], 'arg2': 'foobar'}
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]
之后。。我可以问一下你为什么要重写(一堆)轮子吗
- …等等,等等,等等
作为对编辑的回应,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
这就是我今天使用的,它说明了:
--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
def clean_参数(args):
ret_args=defaultdict(列表)
对于索引,枚举中的k(参数):
如果索引
或者类似的事情)对不起,如果这是愚蠢的,我是一个新手:)
$python3 Test.py a 1 b 2 c 3
argparse完全不同,它用于定义命令行接口。我试图解析任意命令行接口。这个脚本的每次调用都会有不同的参数。我认为使用argparse仍然可以做到这一点。如果你不想使用它,那么你别无选择,只能自己为参数编写一个解析器。是的,我也不知道如何用标准库解析任意参数……5年后这仍然没有解决吗?我需要写这个东西吗?我建议对变量
argsdict
使用a。通过这种方式,您可以摆脱测试中的,并且可以无需担心地进行追加。它使您的代码更简洁、更具表现力,因此更具python风格。这不会产生预期的结果。使用OPs示例,arg1
不会映射到1
和4
,而只映射到4
。例如,如何扩展argparse来解析任意参数?我想不出来。