访问传递给 argparse 中的参数的选项?

Posted

技术标签:

【中文标题】访问传递给 argparse 中的参数的选项?【英文标题】:Accessing the choices passed to argument in argparser? 【发布时间】:2021-12-14 10:08:56 【问题描述】:

是否可以访问传递给参数的选项元组?如果是这样,我该怎么做

例如,如果我有

parser = argparse.ArgumentParser(description='choose location')
parser.add_argument(
    "--location",
    choices=('here', 'there', 'anywhere')
)
args = parser.parse_args()

我可以访问元组('here', 'there', 'anywhere')吗?

【问题讨论】:

【参考方案1】:

原来parser.add_argument实际上返回了关联的Action。您可以从中选择:

>>> import argparse
>>> parser = argparse.ArgumentParser(description='choose location')
>>> action = parser.add_argument(
...     "--location",
...     choices=('here', 'there', 'anywhere')
... )
>>> action.choices
('here', 'there', 'anywhere')

请注意,(AFAIK)这在任何地方都没有记录,可能被视为“实施细节”,因此如有更改,恕不另行通知等。

也没有任何公开可访问的方式来获取存储在ArgumentParser 上的操作添加后。我相信如果您愿意处理实现细节(并承担与之相关的任何风险),它们可以作为parser._actions 使用...


您最好的选择可能是为位置选择创建一个常量,然后在您的代码中使用它:

LOCATION_CHOICES = ('here', 'there', 'anywhere')

parser = argparse.ArgumentParser(description='choose location')
parser.add_argument(
    "--location",
    choices=LOCATION_CHOICES
)
args = parser.parse_args()

# Use LOCATION_CHOICES down here...

【讨论】:

pfft 坚持使用瓷器命令有什么乐趣?让我有一些管道! ;) @AdamSmith -- 据我所知,argparse 内部结构相当稳定(但不要引用我的话 ;-) 对。它们是稳定的,直到它们不稳定并且当用户作为参数输入时您的应用程序(以及随后的世界)意外崩溃 --ritual Iä!_Iä!_Cthulhu_fhtagn!【参考方案2】:

可能有更好的方法,但我在文档中看不到任何方法。如果您知道解析器选项,您应该能够做到:

parser = argparse.ArgumentParser()
parser.add_argument("--location", choices=("here", "there", "everywhere"))

storeaction = next(a for a in parser._actions if "--location" in a.option_strings)

storeaction.choices
# ('here', 'there', 'everywhere')

在 mgilson 的回答中,访问 _actions 属性是未记录的,带下划线的前缀表示“嘿,你可能不应该惹我。”如果这在 Python 版本之间中断,请不要感到惊讶。

【讨论】:

【参考方案3】:

关于add_argument 返回什么的问题,如果您在像ipython 这样的交互式会话中进行任何测试,那么返回会盯着您:

In [73]: import argparse
In [74]: parser=argparse.ArgumentParser()
In [75]: parser.add_argument('foo',choices=['one','two','three'])
Out[75]: _StoreAction(option_strings=[], dest='foo', nargs=None, const=None, default=None, type=None, choices=['one', 'two', 'three'], help=None, metavar=None)
In [76]: _.choices
Out[76]: ['one', 'two', 'three']

请注意,add_argument_groupadd_subparsersadd_parseradd_mutually_exclusive_group 等其他方法都返回可以使用的对象。我认为add_argument 没有记录为返回对象的事实是文档疏忽。通常用户不需要使用它,但作为一个半开发者我一直在使用它。 argparse 的文档不是模块能做什么或不能做什么的正式规范;它更像是一本指导手册,是教程的升级版,但显然不是参考。

parser._actions 的使用很方便,但更深入人心。我已经跟踪了几乎所有的错误/问题,并且想不出任何会引发变化的东西。有大量的潜在更改积压,但由于担心会产生向后兼容性问题,开发人员已被减少到几乎无法动弹。更改文档比更改argparse 的功能更容易。

【讨论】:

以上是关于访问传递给 argparse 中的参数的选项?的主要内容,如果未能解决你的问题,请参考以下文章

python之定义参数模块argparse的基本使用

Pyspark 和使用 UDF:如何将 Python 参数(sys.argv、argparse)传递给 Python Worker?

argparse 模块如何在没有任何参数的情况下添加选项?

python中的argparse模块怎么参数传递

python argh/argparse:如何将列表作为命令行参数传递?

如何根据 Python 中的位置参数与 argparse 的组合设置不同的选项?