我正在尝试使用argparse来解析我正在处理的程序的命令行参数.本质上,我需要支持在可选参数中传播的多个位置参数,但是在这种情况下无法使argparse工作.在实际程序中,我正在使用自定义操作(我需要在每次找到位置参数时存储命名空间的快照),但我可以使用操作复制我遇到的问题append:
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-a', action='store_true')
>>> parser.add_argument('-b', action='store_true')
>>> parser.add_argument('input', action='append')
>>> parser.parse_args(['fileone', '-a', 'filetwo', '-b', 'filethree'])
usage: ipython [-h] [-a] [-b] input
ipython: error: unrecognized arguments: filetwo filethree
Run Code Online (Sandbox Code Playgroud)
我希望这会导致命名空间(a=True, b=True, input=['fileone', 'filetwo', 'filethree']),但无法看到如何做到这一点 - 如果它确实可以.如果有可能的话,我在文档或谷歌中看不到任何一种说法,尽管它很可能(很可能?)我忽略了一些东西.有没有人有什么建议?
srg*_*erg 19
您不能以这种方式将开关(即-a和-b)与位置参数(即fileone,filetwo和filethree)交错.开关必须出现在位置参数之前或之后,而不是介于两者之间.
此外,为了拥有多个位置参数,您需要指定nargs参数add_argument.例如:
parser.add_argument('input', nargs='+')
Run Code Online (Sandbox Code Playgroud)
这告诉argparse我们使用一个或多个位置参数并将它们附加到列表中.有关更多信息,请参阅argparse文档.有了这一行,代码:
parser.parse_args(['-a', '-b', 'fileone', 'filetwo', 'filethree'])
Run Code Online (Sandbox Code Playgroud)
结果是:
Namespace(a=True, b=True, input=['fileone', 'filetwo', 'filethree'])
Run Code Online (Sandbox Code Playgroud)
Wan*_*wei 11
srgerg对位置论证的定义是正确的.为了获得您想要的结果,您必须接受它们作为可选参数,并根据您的需要修改结果命名空间.
您可以使用自定义操作:
class MyAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
# Set optional arguments to True or False
if option_string:
attr = True if values else False
setattr(namespace, self.dest, attr)
# Modify value of "input" in the namespace
if hasattr(namespace, 'input'):
current_values = getattr(namespace, 'input')
try:
current_values.extend(values)
except AttributeError:
current_values = values
finally:
setattr(namespace, 'input', current_values)
else:
setattr(namespace, 'input', values)
parser = argparse.ArgumentParser()
parser.add_argument('-a', nargs='+', action=MyAction)
parser.add_argument('-b', nargs='+', action=MyAction)
parser.add_argument('input', nargs='+', action=MyAction)
Run Code Online (Sandbox Code Playgroud)
这就是你得到的:
>>> parser.parse_args(['fileone', '-a', 'filetwo', '-b', 'filethree'])
Namespace(a=True, b=True, input=['fileone', 'filetwo', 'filethree'])
Run Code Online (Sandbox Code Playgroud)
或者您可以像这样修改结果命名空间:
>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('-a', nargs='+')
>>> parser.add_argument('-b', nargs='+')
>>> parser.add_argument('input', nargs='+')
>>> result = parser.parse_args(['fileone', '-a', 'filetwo', '-b', 'filethree'])
>>> inputs = []
>>> inputs.extend(result.a)
>>> inputs.extend(result.b)
>>> inputs.extend(result.input)
>>> modified = argparse.Namespace(
a = result.a != [],
b = result.b != [],
input = inputs)
Run Code Online (Sandbox Code Playgroud)
这就是你得到的:
>>> modified
Namespace(a=True, b=True, input=['filetwo', 'filethree', 'fileone'])
Run Code Online (Sandbox Code Playgroud)
但是,这两种方法都会导致代码的可读性和可维护性降低.也许最好更改程序逻辑并以不同的方式执行.
使用可选的“附加”操作更有意义:
parser.add_argument('-i', '--input',action='append')
parser.parse_args(['-i','fileone', '-a', '-i','filetwo', '-b', '-i','filethree'])
Run Code Online (Sandbox Code Playgroud)
您可以将选项与单独的位置 ('input1 -a input2 -b input3') 交错,但不能在一个多项位置中交错选项。但是您可以通过两步解析来完成此操作。
import argparse
parser1 = argparse.ArgumentParser()
parser1.add_argument('-a', action='store_true')
parser1.add_argument('-b', action='store_true')
parser2 = argparse.ArgumentParser()
parser2.add_argument('input', nargs='*')
ns, rest = parser1.parse_known_args(['fileone', '-a', 'filetwo', '-b', 'filethree'])
# Namespace(a=True, b=True), ['fileone', 'filetwo', 'filethree']
ns = parser2.parse_args(rest, ns)
# Namespace(a=True, b=True, input=['fileone', 'filetwo', 'filethree'])
Run Code Online (Sandbox Code Playgroud)
http://bugs.python.org/issue14191是一个提议的补丁,它可以通过一次调用来做到这一点:
parser.parse_intermixed_args(['fileone', '-a', 'filetwo', '-b', 'filethree'])
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32913 次 |
| 最近记录: |