同时解析 python 中的多个子命令或以其他方式对解析的参数进行分组

2024-01-04

我正在将 Bash shell 安装程序实用程序转换为 Python 2.7,并且需要实现复杂的 CLI,以便能够解析数十个参数(可能最多约 150 个)。这些是 Puppet 类变量的名称以及十几个通用部署选项(在 shell 版本中可用)。

然而,在我开始添加更多变量后,我面临着几个挑战: 1. 我需要将参数分组到单独的字典中,以便部署选项与 Puppet 变量分开。如果它们被扔到同一个桶中,那么我将不得不编写一些逻辑来对它们进行排序,可能会重命名参数,然后字典合并将不再是微不足道的。 2. 可能存在名称相同但属于不同 Puppet 类的变量,因此我认为子命令可以让我过滤内容并避免名称冲突。

目前我已经通过简单地添加多个解析器来实现参数解析:

parser = argparse.ArgumentParser(description='deployment parameters.')
env_select = parser.add_argument_group(None, 'Environment selection')
env_select.add_argument('-c', '--client_id',  help='Client name to use.')
env_select.add_argument('-e', '--environment', help='Environment name to use.')
setup_type = parser.add_argument_group(None, 'What kind of setup should be done:')
setup_type.add_argument('-i', '--install', choices=ANSWERS, metavar='', action=StoreBool, help='Yy/Nn Do normal install and configuration')
# MORE setup options
...
args, unk = parser.parse_known_args()
config['deploy_cfg'].update(args.__dict__)

pup_class1_parser = argparse.ArgumentParser(description=None)
pup_class1 = pup_class1_parser.add_argument_group(None, 'Puppet variables')
pup_class1.add_argument('--ad_domain', help='AD/LDAP domain name.')
pup_class1.add_argument('--ad_host', help='AD/LDAP server name.')
# Rest of the parameters

args, unk = pup_class1_parser.parse_known_args()
config['pup_class1'] = dict({})
config['pup_class1'].update(args.__dict__)
# Same for class2, class3 and so on.

这种方法的问题是它不能解决问题 2。此外,第一个解析器使用“-h”选项,其余参数不会显示在帮助中。

我尝试过使用选择作为答案的示例 https://stackoverflow.com/questions/10448200/how-to-parse-multiple-sub-commands-using-python-argparse但我无法同时使用这两个命令。

## This function takes the 'extra' attribute from global namespace and re-parses it to create separate namespaces for all other chained commands.
def parse_extra (parser, namespace):
  namespaces = []
  extra = namespace.extra
  while extra:
    n = parser.parse_args(extra)
    extra = n.extra
    namespaces.append(n)

  return namespaces

pp = pprint.PrettyPrinter(indent=4)

argparser=argparse.ArgumentParser()
subparsers = argparser.add_subparsers(help='sub-command help', dest='subparser_name')

parser_a = subparsers.add_parser('command_a', help = "command_a help")
## Setup options for parser_a
parser_a.add_argument('--opt_a1', help='option a1')
parser_a.add_argument('--opt_a2', help='option a2')

parser_b = subparsers.add_parser('command_b', help = "command_b help")
## Setup options for parser_a
parser_b.add_argument('--opt_b1', help='option b1')
parser_b.add_argument('--opt_b2', help='option b2')


## Add nargs="*" for zero or more other commands
argparser.add_argument('extra', nargs = "*", help = 'Other commands')

namespace = argparser.parse_args()
pp.pprint(namespace)
extra_namespaces = parse_extra( argparser, namespace )
pp.pprint(extra_namespaces)

结果我:

$ python argtest.py command_b --opt_b1 b1 --opt_b2 b2 command_a --opt_a1 a1
usage: argtest.py [-h] {command_a,command_b} ... [extra [extra ...]]
argtest.py: error: unrecognized arguments: command_a --opt_a1 a1

当我尝试用两个子解析器定义父解析器时,结果相同。

问题

  1. 我可以以某种方式使用 parser.add_argument_group 进行参数解析,还是仅用于帮助打印中的分组?它将解决问题 1,而不会丢失帮助副作用。将其传递为parse_known_args(namespace=argument_group)(如果我正确地回忆起我的实验)获取所有变量(没关系),但也获取结果字典中的所有 Python 对象内容(这对 hieradata YAML 不利)
  2. 我在第二个示例中缺少什么以允许使用多个子命令?或者 argparse 不可能做到这一点?
  3. 对命令行变量进行分组还有其他建议吗?我查看过 Click,但没有发现对于我的任务来说比标准 argparse 有任何优势。

注意:我是系统管理员,不是程序员,所以请温柔地对待我的非对象风格编码。 :)

谢谢

RESOLVED参数分组通过建议的答案解决hpaulj https://stackoverflow.com/users/901925/hpaulj.

import argparse
import pprint
parser = argparse.ArgumentParser()

group_list = ['group1', 'group2']

group1 = parser.add_argument_group('group1')
group1.add_argument('--test11', help="test11")
group1.add_argument('--test12', help="test12")

group2 = parser.add_argument_group('group2')
group2.add_argument('--test21', help="test21")
group2.add_argument('--test22', help="test22")

args = parser.parse_args()
pp = pprint.PrettyPrinter(indent=4)

d = dict({})

for group in parser._action_groups:
    if group.title in group_list:
        d[group.title]={a.dest:getattr(args,a.dest,None) for a in group._group_actions}

print "Parsed arguments"
pp.pprint(d)

这得到了我对第一个问题的期望结果。直到我有多个同名参数。解决方案可能看起来很难看,但至少它按预期工作。

python argtest4.py --test22 aa  --test11 yy11 --test21 aaa21
Parsed arguments
{   'group1': {   'test11': 'yy11', 'test12': None},
    'group2': {   'test21': 'aaa21', 'test22': 'aa'}}

您的问题太复杂,无法一次性理解和回答。但我会抛出一些初步的想法。

Yes, argument_groups只是帮助中对参数进行分组的一种方式。它们对解析没有影响。

最近另一个 SO 询问有关解析参数组的问题:

是否可以使用 argparse 只解析一个参数组的参数? https://stackoverflow.com/questions/31519997/is-it-possible-to-only-parse-one-argument-groups-parameters-with-argparse

该海报最初想使用一个组作为解析器,但是argparse类结构不允许这样做。argparse是以对象风格编写的。parser=ArguementParser...创建一类对象,parser.add_arguement...创造另一个,add_argument_group...完后还有。您可以通过子类化来自定义它ArgumentParser or HelpFormatter or Action课程等

我提到了一个parents机制。您定义一个或多个父解析器,并使用它们来填充您的“主”解析器。它们可以独立运行(使用 parse_known_args),而“main”用于处理帮助。

我们还讨论了解析后对参数进行分组。 Anamespace是一个简单对象,其中每个参数都是一个属性。它还可以转换为字典。从字典中提取项目组很容易。

关于使用多个子解析器存在一些问题。这是一个尴尬的提议。有可能,但并不容易。子解析器就像向系统程序发出命令。通常每次调用都会发出一个命令。您不嵌套它们或发出序列。您可以让 shell 管道和脚本处理多个操作。

IPython uses argparse解析其输入。它首先捕获帮助,然后发出自己的消息。大多数参数来自配置文件,因此可以使用默认配置、自定义配置和命令行来设置值。这是命名一组非常大的参数的示例。

子解析器允许您使用相同的参数名称,但无法在一次调用中调用多个子解析器,这没有多大帮助。即使您可以调用多个子解析器,它们仍然会将参数放在同一名称空间中。还argparse尝试以独立于顺序的方式处理标记的参数。所以一个--foo命令行末尾的解析方式与开头的解析方式相同。

有一个问题,我们讨论使用参数名称('dest'),例如'group1.argument1',我什至讨论过使用嵌套命名空间。如果有帮助的话我可以查一下。


另一个想法——负载sys.argv并在将其传递给一个或多个解析器之前对其进行分区。您可以将其拆分为某些关键字或前缀等。

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

同时解析 python 中的多个子命令或以其他方式对解析的参数进行分组 的相关文章

  • Django 中的 Rpy2 错误 - 未为“”类型的对象定义转换“py2rpy”

    我以前从未使用过 R 并且正在尝试使用 rpy2 从 python 调用 R 函数 它可以在独立的 python 终端上运行 但不能在 Django 中运行 但rpy2似乎无法将python字符串转换为r对象 我正在使用同事提供的自定义库
  • Python 子进程(ffmpeg)仅在我按 Ctrl-C 程序时启动?

    我正在尝试使用 Cygwin 和 Python 2 7 并行运行一些 ffmpeg 命令 这大概是我所拥有的 import subprocess processes set commands ffmpeg i input mp4 outpu
  • ca 证书 Mac OS X

    我需要在emacs 上安装offlineimap 和mu4e 问题是配置 当我运行 Offlineimap 时 我得到 OfflineIMAP 6 5 5 Licensed under the GNU GPL v2 v2 or any la
  • python 3 argparse 调用函数

    我想在 python3 中创建一个类似命令行 类似 shell 的界面 Argparse 似乎负责解析和显示帮助 错误消息 根据argparse 的 python3 文档 https docs python org 3 5 library
  • 类型错误:float() 参数必须是字符串或数字,而不是“列表”python

    我的 Python 有问题 这是我的代码 def calcola a input b float a 0 split c float a 0 split d float a 0 split e float a 0 split j float
  • 将一维数组转换为下三角矩阵

    我想将一维数组转换为较低的零对角矩阵 同时保留所有数字 我知道numpy tril函数 但它用零替换了一些元素 我需要扩展矩阵以包含所有原始数字 例如 10 20 40 46 33 14 12 46 52 30 59 18 11 22 30
  • Python——捕获异常的效率[重复]

    这个问题在这里已经有答案了 可能的重复 Python 常见问题解答 异常有多快 https stackoverflow com questions 8107695 python faq how fast are exceptions 我记得
  • Tensorflow 不分配完整的 GPU 内存

    Tensorflow 默认分配所有 GPU 内存 但我的新设置实际上只有 9588 MiB 11264 MiB 我预计大约 11 000MiB 就像我的旧设置一样 张量流信息在这里 from tensorflow python client
  • reStructuredText:README.rst 未在 PyPI 上解析

    我有一个托管在 Github 和 PyPI 上的 Python 项目 在 Github 上 https github com sloria TextBlob blob master README rst https github com s
  • 如何使用 PyMongo 在重复键错误后继续插入

    如果我需要在 MongoDB 中插入尚不存在的文档 db stock update one document set document upsert True 将完成这项工作 如果我错了 请随时纠正我 但是 如果我有一个文档列表并想将它们全
  • Selenium 不会在新选项卡中打开新 URL(Python 和 Chrome)

    我想使用 Selenium WebDriver 和 Python 在不同的选项卡中打开相当多的 URL 我不确定出了什么问题 driver webdriver Chrome driver get url1 time sleep 5 driv
  • 具有多个主键的 SQLAlchemy 不会自动设置任何

    我有一个简单的表 class test Base tablename test id Column Integer primary key True title Column String def init self title self
  • 根据列索引重命名 Dataframe 列

    是否有内置函数可以按索引重命名 pandas 数据框 我以为我知道列标题的名称 但事实证明第二列中有一些十六进制字符 根据我接收数据的方式 我将来可能会在第 2 列中遇到这个问题 因此我无法将这些特定的十六进制字符硬编码到 datafram
  • 在 matplotlib 中绘制多边形的并集[重复]

    这个问题在这里已经有答案了 我正在尝试绘制几个多边形的并集matplotlib 具有一定的 alpha 水平 我当前的代码在交叉点处颜色较深 有没有办法让交叉路口与其他地方的颜色相同 import matplotlib pyplot as
  • 如何使用 os.chdir 转到减去最后一步的路径?

    例如 一个方法传递了一个路径作为参数 这个路径可能是 C a b c d 如果我想使用 os chdir 更改为 C a b 怎么办 c 没有最后一个文件夹 os chdir 可以接受 命令吗 os chdir 可以采取 作为论点 是的 然
  • 沿轴 0 重复 scipy csr 稀疏矩阵

    我想重复 scipy csr 稀疏矩阵的行 但是当我尝试调用 numpy 的重复方法时 它只是将稀疏矩阵视为对象 并且只会将其作为 ndarray 中的对象重复 我浏览了文档 但找不到任何实用程序来重复 scipy csr 稀疏矩阵的行 我
  • 如何在Tensorflow中保存估计器以供以后使用?

    我按照教程 TF Layers 指南 构建卷积神经网络 以下是代码 https github com tensorflow tensorflow blob r1 1 tensorflow examples tutorials layers
  • Java/Python 中的快速 IPC/Socket 通信

    我的应用程序中需要两个进程 Java 和 Python 进行通信 我注意到套接字通信占用了 93 的运行时间 为什么通讯这么慢 我应该寻找套接字通信的替代方案还是可以使其更快 更新 我发现了一个简单的修复方法 由于某些未知原因 缓冲输出流似
  • 在python中对列表列表执行行总和和列总和

    我想用python计算矩阵的行和和列和 但是 由于信息安全要求 我无法使用任何外部库 因此 为了创建矩阵 我使用了列表列表 如下所示 matrix 0 for x in range 5 for y in range 5 for pos in
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code

随机推荐

  • window.innerHeight 与 window.outerHeight 计算密度?

    当我开始使用 PhoneGap 一个标尺 开发一个简单的应用程序时 我遇到了一个问题 我的大部分移动背景都是使用原生 Android 所以我就从它开始 我是 javascript 和 html5 以及一般 Web 开发的初学者 Here h
  • 用于从电子表格公式中提取有效单元格引用的正则表达式

    我正在尝试使用 Google Apps 脚本 Javascript 从电子表格公式中提取有效的单元格引用和范围引用 有效的单元格引用是一个或两个字母 后跟不以零开头的连续数字 字母或数字前面可以有也可以没有 字符 整个引用不能以字母 数字或
  • spl_object_hash 匹配,对象不相同

    我在 PHP 中有两个对象变量 我们称它们为 a and b 我认为它们都是同一个对象 事实上 呼吁spl object hash 证实了这一点 但它们各自具有不同的属性 当我跑步时 if spl object hash a spl obj
  • 安装 XML::DOM 模块错误

    我在尝试安装 CPAN 模块时遇到了很多问题 使用 cpan exe 我尝试安装一个模块 例如 install XML DOM 但最终碰壁了 安装完成后提示 dmake exe 不正常 这是我的错误 Microsoft Windows Ve
  • 访问:ConcatRelated 适用于表,但不适用于查询

    我一直在使用Allen Browne s Concat相关 http allenbrowne com func concat html函数 虽然当数据来自表时它工作正常 但当数据来自查询时它不起作用 绿色的 正在运行查询 栏会出现几秒钟 但
  • 如何在 R 中将日期变量分组为月/年?

    我有一个 日期 向量 其中包含 mm dd yyyy 格式的日期 head Entered Date 5 1 1 5 1998 1 5 1998 1 5 1998 1 5 1998 1 5 1998 我正在尝试根据日期绘制频率变量 但我想按
  • 我应该如何在 mongodb 中存储布尔值?

    我看到在 mongodb 中存储布尔信息的三种主要可能性 0 或 1 作为字符串 0 或 1 作为数字 布尔值的 True 或 False 每种方法在使用的存储空间和查询速度方面有哪些优点 缺点 Boolean是本机字段类型BSON htt
  • nginx 缺少站点可用目录

    我在 Centos 6 上安装了 Nginx 并尝试设置虚拟主机 我遇到的问题是我似乎找不到 etc nginx sites available目录 我需要做些什么才能创建它吗 我知道 Nginx 已启动并正在运行 因为我可以浏览它 好吧
  • 发票和发票行:如何存储客户地址信息?

    您好 我正在开发一个发票应用程序 所以总体思路是有两个表 Invoice ID Date CustomerAddress CustomerState CustomerCountry VAT Total InvoiceLine Invoice
  • Spring Security:如何排除某些资源?

    我有以下定义
  • Eclipse:“编辑源查找路径...”

    我正在使用 Eclipse 在 Mac 上进行开发 并拥有实现标准框架回调 onCreate onDestroy onPause 等 的应用程序的框架 当我在回调中设置断点时 调试器会停止并显示一个选项卡 其中显示 ActivityThre
  • 如何将一个存储库重新设置为另一个存储库

    假设我有两个不同的存储库 如下所示 Project 1 Init A B C HEAD1 Project 2 Init D E F G HEAD2 有没有办法将项目 1 Init 到 HEAD 重新设置为项目 2 的 Init 提交 如下所
  • .htaccess 中的多个连字符处理(URL 重写)

    我在 URL 重写方面遇到问题 我在 htaccess 文件中编写了以下规则 RewriteRule c cat php id 1 slug 2 它给了我这样的 URL http localhost actuco c 628Y8x fran
  • 如何获取自己的地址?

    我怎样才能做到这一点 cdef class Tree cdef object key cdef Tree left cdef Tree right cdef PyObject find self key get the address of
  • 根据 stackoverflow 中的问题重新创建 pandas 数据框

    这是一个试图回答有关 pandas 数据框问题的人提出的问题 考虑一个给定数据集的问题 该数据集只是可视化 而不是实际的代码 例如 numbers letters dates all 0 1 a 20 10 2020 NaN 1 2 b 2
  • 分析 Netty 性能

    我正在编写一个 Netty 应用程序 该应用程序在 64 位八核 Linux 机器上运行 Netty 应用程序是一个简单的路由器 它接受请求 传入管道 从请求中读取一些元数据并将数据转发到远程服务 传出管道 该远程服务将向传出管道返回一个或
  • Net Core IWebHostEnvironment 仅获取“c:\”

    我正在尝试将应用程序从 net 移动到 net core 5 并且我正在尝试获取内容根目录 我看到的所有说明都显示在控制器中使用 IHostingEnvironment 然而 使用这个只是让我 c 我怀疑这是因为我试图使用它 不是在控制器中
  • SQL 查询返回包含最近日期等的重复项

    我有一个表 人 有很多列 我需要返回没有 重复 定义如下 的每个条目的完整行以及以下内容 找到该表中共享属性的条目 first name last name 和 work phone 这些是我的重复项 目的 并仅返回其 date modif
  • AttributeError:“历史”对象没有属性“预测” - 拟合训练和测试数据列表

    我正在尝试使用这个的神经网络模型example http machinelearningmastery com regression tutorial keras deep learning library python 我正在将值列表拟合
  • 同时解析 python 中的多个子命令或以其他方式对解析的参数进行分组

    我正在将 Bash shell 安装程序实用程序转换为 Python 2 7 并且需要实现复杂的 CLI 以便能够解析数十个参数 可能最多约 150 个 这些是 Puppet 类变量的名称以及十几个通用部署选项 在 shell 版本中可用