被删除的答案和评论表明有些混淆,不清楚你想要什么。所以我会增加这种混淆。
通常情况下,解析器不会记录选项字符串。但是它提供给 Action
的 __call__
方法。因此,自定义 Action 类可以保存它。argparse 文档中的 FooAction
自定义类示例说明了这一点。
如果我定义这个操作子类:
In [324]: class PassThru(argparse._StoreAction):
def __call__(self, parser, namespace, values, option_string=None):
setattr(namespace, self.dest, [values, option_string])
In [324]: p.add_argument('-o','--other',action=PassThru)
选项字符串与值(“-o”或“--other”)一起记录:
In [322]: p.parse_args('-p test -o teseting'.split())
Out[322]: Namespace(other=['teseting', '-o'], pass_me_on='test')
In [323]: p.parse_args('-p test --other teseting'.split())
Out[323]: Namespace(other=['teseting', '--other'], pass_me_on='test')
很明显,option_string和value可以以不同的顺序、在字典中、作为Namespace的单独属性等方式记录。
有其他方法将选项传递给另一个程序,特别是如果包装解析器本身不需要处理这些选项。
argparse
从sys.argv[1:]
获取参数,并且不会更改它。因此,即使您的解析器使用了一些参数,您也可以将该列表全部或部分传递给popen
。
argparse文档提供了一个示例,在nargs=REMAINDER
下解析自己的一些参数,并收集其余参数以传递给另一个程序。这是他们的示例:
>>> parser = argparse.ArgumentParser(prog='PROG')
>>> parser.add_argument('--foo')
>>> parser.add_argument('command')
>>> parser.add_argument('args', nargs=argparse.REMAINDER)
>>> print(parser.parse_args('--foo B cmd --arg1 XX ZZ'.split()))
Namespace(args=['--arg1', 'XX', 'ZZ'], command='cmd', foo='B')
所以您可以使用类似以下方式调用
popen
:
plist = ['wrapped_program']
plist.extend(args.args)
popen(plist, ...)
使用
parse.parse_known_args
也可以将未解析的单词收集到一个“extras”列表中。文档的这一部分讨论了将这些字符串传递给另一个程序(就像您正在做的那样)。与REMAINDER情况相反,额外的内容不必是最后一个。
当然,这些只有在此解析器自己不需要
--pattern
时才有效。如果它进行了解析,则不会出现在REMAINDER或extras中。在这种情况下,您将不得不将其添加回您给
popen
的列表中。
我会对您的解析器进行微调:
pass_1 = 'passed'
dpass_` = '--'+pass_
parser = argparse.ArgumentParser()
parser.add_argument("-p", dpass_1, help="Pass me on")
parser.add_argument("-k", "--arg-for-wrapper")
args = parser.parse_args()
process = Popen(['wrapped_program', dpass_1, getattr(args, pass_1)], ...)
另一种选择:
parser = argparse.ArgumentParser()
pass_action = parser.add_argument("-p", '--pass-me-on', help="Pass me on")
parser.add_argument("-k", "--arg-for-wrapper")
args = parser.parse_args()
如果你在 shell 中打印
pass_action
,你会得到类似以下的结果:
_StoreAction(option_strings=['-p', '--pass-me-on'], dest='pass_me_on', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
因此,您可以从该对象中提取--name
和dest
,如下所示:
process = Popen(['wrapped_program', pass_action.option_strings[-1], getattr(args, pass_action.dest), ...], ...)
你需要查看
sys.argv
,以确定使用了哪个选项字符串(长、短或其他)。解析器不会在任何地方记录这一点。
请注意,'--pass-me-on' 产生了
dest='pass_me_on'
。将
-
转换为
_
可能会使从一个字符串推导出另一个字符串变得复杂。
如果你有一个
dest
字符串,你必须使用
getattr
从 args 命名空间中提取它,或使用
vars(args)[dest]
(字典访问)。
另一个问题是,如果
--patten
有
nargs='+',
那么它的值将是一个列表,而不是一个字符串。当将其合并到
popen
参数列表中时,你需要小心。
pattern_str = '--pattern'
,然后...add_argument(... pattern_str...)
。这样,只有一个维护点。 - Ami Tavory