在 Python3.7 之前的版本中,应该如何在 argparse-module 中处理 interspersed/intermixed 参数?
How interspersed/intermixed arguments should be handled in argparse-module in versions prior to Python3.7?
当遵循 official documentation 从 optparse
升级到 argparse
时,以下简单解析器
import optparse
def parse_with_optparser(args):
opt_parser = optparse.OptionParser()
opt_parser.add_option('-a', action="store_true")
return opt_parser.parse_args(args)
变为:
def parse_with_argparser(args):
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('-a', action="store_true")
arg_parser.add_argument("sources", nargs='*')
return arg_parser.parse_args(args)
即添加了一个额外的位置参数 sources
。
但是,optparse
默认支持散布(或混合在 argparse
-parlance 中)参数,即我们可以调用 successful for
args = ['file1', '-a', 'file2']
parse_with_optparser(args)
# ({'a': True}, ['file1', 'file2'])
但 argparse
不支持混合参数,使用它会导致错误:
parse_with_argparser(args)
# error: unrecognized arguments: file2
因为 Python3.7 有 parse_intermixed_args
(而不是 parse_args
),它处理 interspersed/intermixed 参数的方式与 optparse
相同。但是,该框架的目标是 Python2.7 和 Pyton>=3.3,因此使用 parse_intermixed_args
并不能解决问题。
在 Python3.7 之前的版本中 argparse
应该如何处理 interspersed/intermixed 参数?
一些测试用例:
Input Output
['file1', 'file2', '-a'] Namespace(a=True, sources=['file1', 'file2'])
['-a', 'file1', 'file2'] Namespace(a=True, sources=['file1', 'file2'])
['file1', '-a', 'file2'] Namespace(a=True, sources=['file1', 'file2'])
['file1', '-a', '-b'] error (-b is unknown option)
我遵循@hpaulj 的建议并使用 parse_known_args
能够在 post 处理步骤中手动处理混合选项:
import argparse
def parse_with_argparser(args):
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('-a', action="store_true")
# thus, "sources" is also a part of the help-message:
arg_parser.add_argument("sources", nargs='*')
# collecting unknown-options for post processing,
# rather than exiting directly:
result, unknown = arg_parser.parse_known_args(args)
# post processing:
for x in unknown:
# filter out unknown options (like -b)
# exit with error
if x.startswith('-'):
arg_parser.error("unknown argument "+x)
# that must be one of the remaining sources:
getattr(result, 'sources').append(x)
return result
它似乎比 parse_intermixed_args
的 copying-and-pasting 代码更容易,因为 arparse
模块无法处理 Python<3.7 中的 narg==SUPPRESS
,它是补丁需要。
当遵循 official documentation 从 optparse
升级到 argparse
时,以下简单解析器
import optparse
def parse_with_optparser(args):
opt_parser = optparse.OptionParser()
opt_parser.add_option('-a', action="store_true")
return opt_parser.parse_args(args)
变为:
def parse_with_argparser(args):
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('-a', action="store_true")
arg_parser.add_argument("sources", nargs='*')
return arg_parser.parse_args(args)
即添加了一个额外的位置参数 sources
。
但是,optparse
默认支持散布(或混合在 argparse
-parlance 中)参数,即我们可以调用 successful for
args = ['file1', '-a', 'file2']
parse_with_optparser(args)
# ({'a': True}, ['file1', 'file2'])
但 argparse
不支持混合参数,使用它会导致错误:
parse_with_argparser(args)
# error: unrecognized arguments: file2
因为 Python3.7 有 parse_intermixed_args
(而不是 parse_args
),它处理 interspersed/intermixed 参数的方式与 optparse
相同。但是,该框架的目标是 Python2.7 和 Pyton>=3.3,因此使用 parse_intermixed_args
并不能解决问题。
在 Python3.7 之前的版本中 argparse
应该如何处理 interspersed/intermixed 参数?
一些测试用例:
Input Output
['file1', 'file2', '-a'] Namespace(a=True, sources=['file1', 'file2'])
['-a', 'file1', 'file2'] Namespace(a=True, sources=['file1', 'file2'])
['file1', '-a', 'file2'] Namespace(a=True, sources=['file1', 'file2'])
['file1', '-a', '-b'] error (-b is unknown option)
我遵循@hpaulj 的建议并使用 parse_known_args
能够在 post 处理步骤中手动处理混合选项:
import argparse
def parse_with_argparser(args):
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('-a', action="store_true")
# thus, "sources" is also a part of the help-message:
arg_parser.add_argument("sources", nargs='*')
# collecting unknown-options for post processing,
# rather than exiting directly:
result, unknown = arg_parser.parse_known_args(args)
# post processing:
for x in unknown:
# filter out unknown options (like -b)
# exit with error
if x.startswith('-'):
arg_parser.error("unknown argument "+x)
# that must be one of the remaining sources:
getattr(result, 'sources').append(x)
return result
它似乎比 parse_intermixed_args
的 copying-and-pasting 代码更容易,因为 arparse
模块无法处理 Python<3.7 中的 narg==SUPPRESS
,它是补丁需要。