python - 来自子解析器的顶级解析器上的 Python argparse set_defaults
问题描述
我有一个argparse
带有多个子解析器的程序。如果未指定顶级参数的值,我希望它取决于子解析器的选择。这可以通过set_defaults()
在每个子解析器上使用来部分完成。但是,传递的值不像真正的默认值那样起作用,因为即使显式提供了顶级参数,它也具有优先权。
我是否在argparse
模块中遗漏了一些允许特定于子解析器的默认值屈服于顶级解析器的东西?下面是一个演示我想要的用例的玩具示例
import argparse
# Top-level parser
parser = argparse.ArgumentParser()
parser.add_argument('-t', '--time', type=str)
# Add subparsers with options
actions = parser.add_subparsers(dest='action', metavar='action')
actions.required = True
eat = actions.add_parser('eat')
eat.add_argument('-f', '--food', type=str, default='pizza')
order = actions.add_parser('order')
order.add_argument('-i', '--item', type=int, required=True)
# Attempt to set main parser's --time depending on subparser selection
eat.set_defaults(time='now')
order.set_defaults(time='later')
# Tests that work as expected
print(parser.parse_args(['order', '--item', 0])) # Namespace(action='order', item=0, time='later')
print(parser.parse_args(['eat'])) # Namespace(action='eat', food='pizza', time='now')
# Tests that DO NOT work
# Actual result: the --time flag of `parser` is ignored in preference of each subparser's default
# Desired result: explicit usage of --time should override the subparser defaults like the comments below
# Namespace(action='order', item=0, time='before')
# Namespace(action='eat', food='pizza', time='after')
print(parser.parse_args(['--time', 'before', 'order', '--item', 0]))
print(parser.parse_args(['--time', 'after', 'eat']))
解决方案
似乎子解析器参数覆盖了
从顶级解析器创建的命名空间条目,因为它们具有
相同的名称。所以命名空间最终只有一个“时间”
条目(而不是一个用于顶级解析器,一个用于
子解析器);它的值是写入它的最后一个值:
子解析器的值。
或者,在使用特定的子解析器之前,也许只在主解析器中使用 arg,
并更改它的默认值(在主解析器中) ?
import argparse
parserMain = argparse.ArgumentParser()
parserMain.add_argument('--arg', type=str)
subparsers = parserMain.add_subparsers()
parserX = subparsers.add_parser('x')
# This would overwrite the value of 'arg' in the Namespace:
#parserX.set_defaults(arg='defaultValForX')
# So, set default in main parser, before using sub-parser:
parserMain.set_defaults(arg='defaultValForX')
print(parserMain.parse_args(['x']))
print(parserMain.parse_args(['--arg', 'explicitVal', 'x']))
parserY = subparsers.add_parser('y')
# This would overwrite the value of 'arg' in the Namespace:
#parserY.set_defaults(arg='defaultValForY')
# So, set default in main parser, before using sub-parser:
parserMain.set_defaults(arg='defaultValForY')
print(parserMain.parse_args(['y']))
print(parserMain.parse_args(['--arg', 'explicitVal', 'y']))
推荐阅读
- oauth-2.0 - 从 Token 获取角色
- linkedin - 如何使用用户 ID 估算某人加入 LinkedIn 的日期
- python - 同一列上的 Numpy.where 导致空数据框
- forms - 为什么自动建议菜单会将所选项目添加到多个输入中?
- html - 如何防止侧边栏滚动 flexdashboard 输入?R 和 Rmarkdwown
- flutter - 带有 TextField 的 setState 的 onChanged 方法不会更新结果?
- cocoapods - 是什么控制 CocoaPods 是显示登录页面还是仅显示 Git 存储库的链接?
- sql - 连接到多个服务器和数据库并运行相同的 SQL 语句
- vega - 在 vega 中将纪元时间戳转换为日期
- phpspreadsheet - 如何不使用 phpspreadsheet html 阅读器在单元格值中写入注释