我正在编写一个用于运行bash命令的实用程序,它实际上将字符串和列表可选参数作为输入,并使用可选参数来插入字符串。
我希望它能像这样工作:
interpolate.py Hello {user_arg} my name is {computer_arg} %% --user_arg=john --computer_arg=hal
%%
是一个分隔符,它将要插入的字符串与参数分开。以下是用于插入字符串的参数。在这种情况下,用户选择user_arg
和computer_arg
作为参数。程序无法预先知道用户将选择哪个参数名称。
我的问题是如何解析参数?我可以在分隔符上简单地分割输入参数,但我无法弄清楚如何让optparse只是将可选参数列表作为字典给出,而不事先指定它们。有没有人知道如何在不写大量正则表达式的情况下做到这一点?
答案 0 :(得分:2)
好吧,如果使用' - '将参数与参数而不是%%分开,optparse / argparse只会将参数作为普通列表(将它们视为位置参数而不是切换)。在那之后它不是'很多'正则表达式,它只是一个分裂:
for argument in args:
if not argument.startswith("--"):
# decide what to do in this case...
continue
arg_name, arg_value = argument.split("=", 1)
arg_name = arg_name[2:]
# use the argument any way you like
答案 1 :(得分:2)
使用argparse,您可以使用parse_known_args
方法来使用预定义的参数和任何其他参数。例如,使用以下脚本
import sys
import argparse
def main(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument('string', type=str, nargs='*',
help="""String to process. Optionally with interpolation
(explain this here...)""")
args, opt_args = parser.parse_known_args(argv)
print args
print opt_args
return 0
if __name__=='__main__':
sys.exit(main(sys.argv[1:]))
并使用
进行调用python script.py Hello, my name is {name} --name=chris
产生以下输出:
Namespace(string=['Hello,' 'my', 'name', 'is', '{name}'])
['--name=chris']
剩下要做的就是遍历args
命名空间,查找{...}
形式的字符串,并将其替换为opt_args
中的相应元素(如果存在)。 (我不确定argparse是否可以自动进行参数插值,上面的例子是我想到的唯一直接解决方案)。
答案 2 :(得分:1)
对于这样的事情,你真的不需要optparse或argparse - 这种情况下这些库的好处很少使用(比如孤独的-v
类型参数,检查无效选项,值验证和等等)
def partition_list(lst, sep):
"""Slices a list in two, cutting on index matching "sep"
>>> partition_list(['a', 'b', 'c'], sep='b')
(['a'], ['c'])
"""
if sep in lst:
idx = lst.index(sep)
return (lst[:idx], lst[idx+1:])
else:
return (lst[:], )
def args_to_dict(args):
"""Crudely parses "--blah=123" type arguments into dict like
{'blah': '123'}
"""
ret = {}
for a in args:
key, _, value = a.partition("=")
key = key.replace("--", "", 1)
ret[key] = value
return ret
if __name__ == '__main__':
import sys
# Get stuff before/after the "%%" separator
string, args = partition_list(sys.argv[1:], "%%")
# Join input string
string_joined = " ".join(string)
# Parse --args=stuff
d = args_to_dict(args)
# Do string-interpolation
print string_joined.format(**d)