python argparse store --foo=bar as args.key='foo', args.value='bar'

2023-12-08

我想解析一个具有互斥选项组的命令行。通常,我只会使用--foo bar这会在命名空间中产生,args.foo = 'bar'

但是,由于所有这些选项都是互斥的,并且我对选项名称和传递给选项的参数都感兴趣,并且我有几个需要提供给下游的选项,所以我真正想要的是去取回args.option_name = 'foo', args.option_value = 'bar'在我的命名空间中而不是args.foo='bar'.

我所做的是:

class KeyAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        setattr(namespace, self.dest, values) 
        setattr(namespace, self.dest+'_key', option_string)

frob = parser.add_mutually_exclusive_group()
frob.add_argument('--foo', dest='thing', nargs='?', action=KeyAction)
frob.add_argument('--nar', dest='thing', nargs='?', action=KeyAction)

运行时,我的命名空间将如下所示:

Namespace(thing_key='--foo', thing='bar')

when --foo=bar被解析。当然,遗憾的是,如果 --foo 或 --nar 从未传入,namespace.thing_key没有被定义,所以我必须使用getattr().

动作覆盖虽然有效,但似乎不太正确。

我怀疑 argparse 背后的聪明人已经以某种方式正确地实现了这一点,而我只是在文档和我的文档中遗漏了它 读取 argparse.py。

最好的、正确的、Pythonic 的方法是什么?子解析器? 我正在使用 python 3.5。

因此,我最终使用了您两个答案中的数据来构建这个,它处理选项、它的参数,并在初始化时合理地设置所有内容。

非常感谢您的提示、线索和验证。我很惊讶这之前没有出现在 argparse 中并成为标准化的东西。它is一个极端情况,但并不是那么极端的情况当使用互斥选项时.

    class ValueAction(argparse.Action):
        """Override to store both the format type as well as the argument"""
        # pylint: disable=too-few-public-methods
        def __init__(self, option_strings, dest, **kwargs):
            self._dest = dest
            dest = dest + '_arguments'
            container = kwargs.pop('container')
            kwargs['action'] = kwargs.pop('subaction')
            action_class = container._pop_action_class(kwargs)
            if not callable(action_class):
                raise ValueError('unknown action "%s"' % (action_class,))
            self._action = action_class(option_strings, dest, **kwargs)
            super().__init__(option_strings, dest, **kwargs)

        def __call__(self, parser, namespace, values, option_string=None):
            self._action(parser, namespace, values, option_string)
            if isinstance(option_string, str):
                while option_string[0] in parser.prefix_chars:
                    option_string = option_string[1:]
            setattr(namespace, self._dest, option_string)

据我了解,您希望能够指定一个复合操作,以便既保存一个命名空间槽中使用的选项名称,又执行某些其他操作的更新。例如,您希望能够编写如下内容:

group = argparse.mutually_exclusive_group()
group.add_argument('--foo', action=StoreOption, subaction='store_true')
group.add_argument('--bar', nargs='?', action=StoreOption, subaction='store')

动作类是StoreOption,但它会调用指定的操作subaction对命名空间对象执行其他更新。

我得到的工作代码(经过非常有限的测试)如下所示:

import argparse

class StoreOption(argparse.Action):
  def __init__(self, **kwargs):
    kwargs['action'] = kwargs.pop('subaction')
    container = kwargs.pop('container')

    action_class = container._pop_action_class(kwargs)
    if not callable(action_class):
      raise ValueError('unknown action "%s"' % (action_class,))

    kwargs['dest'] = 'thing'
    self._action = action_class(**kwargs)
    print "_action:", self._action

    super(StoreOption, self).__init__(
        option_strings= self._action.option_strings,
        dest= self._action.dest,
        nargs= self._action.nargs,
        const= self._action.const,
        default= self._action.default,
        type= self._action.type,
        choices= self._action.choices,
        required= self._action.required,
        help= self._action.help,
        metavar= self._action.metavar)

  def __call__(self, parser, namespace, values, option_string=None):
    print "got here:", option_string, namespace
    setattr(namespace, 'key', option_string)
    self._action(parser, namespace, values, option_string)

A test:

parser = argparse.ArgumentParser(prog='PROG')
group = parser.add_mutually_exclusive_group()
group.add_argument('--foo', container=group, action=StoreOption, subaction='store_true')
group.add_argument('--bar', container=group, nargs=2, action=StoreOption, subaction='store')

print parser.parse_args(['--bar', 'asd', 'qwe'])
-- prints: Namespace(key='--bar', thing=['asd', 'qwe'])

基本上StoreOption是一个包装另一个 Action 的 Action(由subaction)。添加参数时,您需要传递container=参数,以便它可以构造子动作。此外,还需要对关键字参数进行一些修改,以便为子操作正确设置它们。

同样,这已经经过了非常有限的测试,因此它可能不适用于所有子操作,但它应该为您指明正确的方向。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python argparse store --foo=bar as args.key='foo', args.value='bar' 的相关文章

  • 在PyGI中获取窗口句柄

    在我的程序中 我使用 PyGObject PyGI 和 GStreamer 在 GUI 中显示视频 该视频显示在Gtk DrawingArea因此我需要获取它的窗口句柄realize 信号处理程序 在 Linux 上 我使用以下方法获取该句
  • 定义Python源代码编码的正确方法

    PEP 263 http www python org dev peps pep 0263 定义如何声明Python源代码编码 通常 Python 文件的前两行应以以下内容开头 usr bin python coding
  • McNemar 在 Python 中的测试以及分类机器学习模型的比较 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有用 Python 实现的好的 McNemar 测试 我在 Scipy stats 或 Scikit
  • Python re无限执行

    我正在尝试执行这段代码 import re pattern r w w s re compiled re compile pattern results re compiled search COPRO HORIZON 2000 HOR p
  • 指示电子邮件的类型

    我有以下自动化程序 它将电子邮件发送给我自己 并添加了特定的链接 import win32com client as win32 import easygui import tkinter as to from tkinter import
  • 将 C++ 指针作为参数传递给 Cython 函数

    cdef extern from Foo h cdef cppclass Bar pass cdef class PyClass cdef Bar bar def cinit self Bar b bar b 这总是会给我类似的东西 Can
  • 如何获取numpy.random.choice的索引? - Python

    是否可以修改 numpy random choice 函数以使其返回所选元素的索引 基本上 我想创建一个列表并随机选择元素而不进行替换 import numpy as np gt gt gt a 1 4 1 3 3 2 1 4 gt gt
  • 是否有一个包可以维护所有带有符号的货币列表?

    是否有一个 python 包提供所有 或相当完整 货币的列表与符号 如美元的 有优秀的pycountry 贪财的 https github com limist py moneyed and ccy http code google com
  • 如何使用 Homebrew 在 Mac 上安装 Python 2 和 3?

    我需要能够在 Python 2 和 3 之间来回切换 我如何使用 Homebrew 来做到这一点 因为我不想弄乱路径并陷入麻烦 现在我已经通过 Homebrew 安装了 2 7 我会用pyenv https github com yyuu
  • python 中的 h2o 框架子集

    如何在 python 中对 h2o 框架进行子集化 如果 x 是一个 df 并且 Origin 是一个变量 那么在 pandas 中我们通常可以通过以下方式进行子集化 x x Origin AAF 但使用 h2o 框架会出现以下错误 H2O
  • 在 Mac OS X 上安装 libxml2 时出现问题

    我正在尝试在我的 Mac 操作系统 10 6 4 上安装 libxml2 我实际上正在尝试在 Python 中运行 Scrapy 脚本 这需要我安装 Twisted Zope 现在还需要安装 libxml2 我已经下载了最新版本 2 7 7
  • 使用标签或 href 传递 Django 数据

    我有一个包含链接的表 当单击该链接进行更多操作时 我想将一些数据传递给我的函数 my html table tbody for query in queries tr td value a href internal my func que
  • App Engine 实体到字典

    将 google app engine 实体 在 python 中 复制到字典对象的好方法是什么 我正在使用 db Expando 对象 所有属性均为扩展属性 Thanks 有一个名为foo尝试 foo dict
  • 检索 geodjango 多边形对象的边界框

    如何在 geodjango 中获取 MultiPolygon 对象的边界框 在 API 中找不到任何内容http geodjango org docs geos html http geodjango org docs geos html
  • 如何在 Seaborn 中的热图轴上表达类

    我使用 Seaborn 创建了一个非常简单的热图 显示相似性方阵 这是我使用的一行代码 sns heatmap sim mat linewidths 0 square True robust True sns plt show 这是我得到的
  • numpy polyfit 中使用的权重值是多少以及拟合误差是多少

    我正在尝试对 numpy 中的某些数据进行线性拟合 Ex 其中 w 是该值的样本数 即对于点 x 0 y 0 我只有 1 个测量值 该测量值是2 2 但对于这一点 1 1 我有 2 个测量值 值为3 5 x np array 0 1 2 3
  • 根据多个阈值将 SciPy 分层树状图切割成簇

    我想将 SciPy 的树状图切割成多个具有多个阈值的簇 我尝试过使用 fcluster 但它只能削减一个阈值 例如 这是我从另一个问题中摘取的一段代码 import pandas data pandas DataFrame total ru
  • 仅允许正小数

    在我的 Django 模型中 我创建了一个如下所示的小数字段 price models DecimalField u Price decimal places 2 max digits 12 显然 价格为负或零是没有意义的 有没有办法将小数
  • 将时间添加到日期时间

    我有一个像这样的日期字符串 然后使用strptime 所以就像这样 my time datetime datetime strptime 07 05 15 m d Y 现在我想添加 23 小时 59 分钟my time 我努力了 timed
  • 如何绘制更大的边界框和仅裁剪边界框文本 Python Opencv

    我正在使用 easyocr 来检测图像中的文本 该方法给出输出边界框 输入图像如下所示 Image 1 Image 2 使用下面的代码获得输出图像 But I want to draw a Single Bigger bounding bo

随机推荐