使用 argparse 从选项中获取唯一值列表
Using argparse to get a list of unique values from choices
我有一个程序,它的参数可以从定义的列表中获取值。每个值只能传递一次。必须至少选择一个值。如果未选择任何值,则默认为选择所有值。以下代码展示了所需的行为。
import argparse
############################# Argument parsing
all_targets = ["bar", "baz", "buzz"]
p = argparse.ArgumentParser()
p.add_argument(
"--targets", default=all_targets, choices=all_targets, nargs="+",
)
args = p.parse_args()
targets = args.targets
if len(targets) > len(set(targets)):
raise ValueError("You may only foo every target once!")
############################## Actual program
for target in targets:
print(f"You just foo'ed the {target}!")
但是,现在我正在处理解析后的参数验证,这似乎是一种反模式,因为 argparse 通常在解析步骤中进行类型验证等。
我可以从 ArgumentParser
得到与上面相同的行为而不是对参数进行 post 检查吗?
@chepner 提供了一些替代方案。对我来说最自然的一种是 Actions 的使用。结合单性检查可以按如下方式完成:
import argparse
class CheckUniqueStore(argparse.Action):
"""Checks that the list of arguments contains no duplicates, then stores"""
def __call__(self, parser, namespace, values, option_string=None):
if len(values) > len(set(values)):
raise argparse.ArgumentError(
self,
"You cannot specify the same value multiple times. "
+ f"You provided {values}",
)
setattr(namespace, self.dest, values)
############################# Argument parsing
all_targets = ["bar", "baz", "buzz"]
p = argparse.ArgumentParser()
p.add_argument(
"--targets",
default=all_targets,
choices=all_targets,
nargs="+",
action=CheckUniqueStore,
)
args = p.parse_args()
############################## Actual program
for target in args.targets:
print(f"You just foo'ed a {target}!")
我有一个程序,它的参数可以从定义的列表中获取值。每个值只能传递一次。必须至少选择一个值。如果未选择任何值,则默认为选择所有值。以下代码展示了所需的行为。
import argparse
############################# Argument parsing
all_targets = ["bar", "baz", "buzz"]
p = argparse.ArgumentParser()
p.add_argument(
"--targets", default=all_targets, choices=all_targets, nargs="+",
)
args = p.parse_args()
targets = args.targets
if len(targets) > len(set(targets)):
raise ValueError("You may only foo every target once!")
############################## Actual program
for target in targets:
print(f"You just foo'ed the {target}!")
但是,现在我正在处理解析后的参数验证,这似乎是一种反模式,因为 argparse 通常在解析步骤中进行类型验证等。
我可以从 ArgumentParser
得到与上面相同的行为而不是对参数进行 post 检查吗?
@chepner 提供了一些替代方案。对我来说最自然的一种是 Actions 的使用。结合单性检查可以按如下方式完成:
import argparse
class CheckUniqueStore(argparse.Action):
"""Checks that the list of arguments contains no duplicates, then stores"""
def __call__(self, parser, namespace, values, option_string=None):
if len(values) > len(set(values)):
raise argparse.ArgumentError(
self,
"You cannot specify the same value multiple times. "
+ f"You provided {values}",
)
setattr(namespace, self.dest, values)
############################# Argument parsing
all_targets = ["bar", "baz", "buzz"]
p = argparse.ArgumentParser()
p.add_argument(
"--targets",
default=all_targets,
choices=all_targets,
nargs="+",
action=CheckUniqueStore,
)
args = p.parse_args()
############################## Actual program
for target in args.targets:
print(f"You just foo'ed a {target}!")