Python argparse - 将选项与字典一起使用的选项

3

我正在尝试使用argparse解析一些选项。我发现有些类似的问题被讨论过,并且在Options with Options with Python argparse?中找到了一个看似合理的解决方案,由Owen提供。

我想能够指定以下内容:

script.py infile --line <path to file1> beglab='str1' endlab='str2' 
                 --line <path to file2>  
                 --line <path to file3> beglab='str3' 
                 outfile

--line选项可以多次指定。一开始我没有额外的参数来使用line选项,使用以下命令可以轻松创建文件列表:

parser.add_argument("--line", action='append')

现在我需要可选地为每条线添加标签。每条线可以与0、1或2个标签相关联,如上所示。这就是为什么我觉得提供的链接中的示例似乎很合适,但不幸的是当我尝试时:
parser.add_argument("--line", action='append', nargs="+")

并运行:

script.py infile --line somefile beglab='A' endlab='B' 
                 --line otherfile beglab='a' endlab='b' outfile

或者
script.py infile --line somefile outfile

我收到一个错误,指出参数过少。如果我从命令中删除--line选项,只保留位置参数,则可以正常运行,因此我知道没有漏掉任何必需的内容。所以我去查看了nargs选项。如果指定了--line,则它必须至少有文件名,因此我认为nargs='+'是适当的选项,在帮助文档[--line LINE [LINE ...]]中看起来很正确,所以我真的很困惑这个错误是从哪里来的。
我很乐意考虑其他处理方法,我只是喜欢用这种方式提供输入,并用它们创建一个字典的简单性。

'+'是贪婪的,将所有字符串分配给--line(直到结尾或下一个--)。因此,对于outfile没有剩余。有一个已经探索了为下一个位置保留值的错误/问题,但是这不会很快改变。这个问题在其他SO问题中也有讨论过。但是接受的答案是好的。 - hpaulj
2个回答

2
你想要构建的解析器是有歧义的。如果endlab='b'是可选的,那么argparse无法确定操作员是打算将outfile作为--line参数还是位置参数。
你不必更改解析器,但必须更改命令行:
尝试:
script.py infile outfile
          --line somefile beglab='A' endlab='B' 
          --line otherfile beglab='a' endlab='b' 

或者:

script.py infile 
          --line somefile beglab='A' endlab='B' 
          --line otherfile beglab='a' endlab='b' 
          --
          outfile

我在我的问题中几乎问到了它如何知道何时停止。所以答案是它不知道,这实际上解释了错误消息!这真是一件非常简单的事情。 - emmalg
我刚刚注意到你的第一个示例末尾多了一个“outfile”,需要将其删除。 - emmalg
谢谢,@emmalg。我已经将它移除了。 - Robᵩ

0

我不确定如何使用argparse来完成这个任务,但为了简单起见,我会考虑做一些类似于:

--line <path_to_file>,<beglab>,<endlab>

然后在代码中或使用argparse的自定义类型功能解析参数。您可以让自定义类型函数返回一个像{'filepath':'<path_to_file>', 'beglab':'<beglab>', 'endlab':'<endlab>'}这样的字典。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接