argparse:展平 action='append' 的结果 [英] argparse: flatten the result of action='append'

查看:18
本文介绍了argparse:展平 action='append' 的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想制作一个支持表单参数列表的脚本

./myscript --env ONE=1,TWO=2 --env THREE=3

这是我的尝试:

导入 argparse解析器 = argparse.ArgumentParser()parser.add_argument('--环境',type=lambda s: s.split(','),动作='追加',)选项 = parser.parse_args()打印选项.env$ ./myscript --env ONE=1,TWO=2 --env THREE=3[['ONE=1', 'TWO=2'], ['THREE=3']]

当然我可以在后期处理中解决这个问题:

options.env = [x for y in options.env for x in y]

但我想知道是否有某种方法可以直接从 argparse 中获取扁平化列表,这样我就不必在添加新内容时在脑海中保留事后需要扁平化的内容"列表程序的选项.

如果我使用 nargs='*' 而不是 type=lambda...,同样的问题也适用.

导入 argparse解析器 = argparse.ArgumentParser()parser.add_argument('--环境',nargs='+',动作='追加',)选项 = parser.parse_args()打印选项.env$ ./myscript --env ONE=1 TWO=2 --env THREE=3[['ONE=1', 'TWO=2'], ['THREE=3']]

解决方案

自 Python 3.8 起,扩展"可直接在 stdlib 中使用.如果您只需要支持 3.8+,则不再需要自己定义它.stdlib扩展"操作的使用与最初描述的这个答案完全相同:

<预><代码>>>>导入参数解析>>>解析器 = argparse.ArgumentParser()>>>_ = parser.add_argument('--env', nargs='+', action='extend')>>>parser.parse_args(["--env", "ONE", "TWO", "--env", "THREE"])命名空间(env=['ONE', 'TWO', 'THREE'])

<小时>

不幸的是,默认情况下 ArgumentParser 中没有提供 extend 操作.但是注册一个并不难:

导入 argparse类 ExtendAction(argparse.Action):def __call__(self, parser, namespace, values, option_string=None):items = getattr(namespace, self.dest) 或 []items.extend(值)setattr(命名空间,self.dest,项目)解析器 = argparse.ArgumentParser()parser.register('action', 'extend', ExtendAction)parser.add_argument('--env', nargs='+', action='extend')args = parser.parse_args()打印(参数)

演示:

$ python/tmp/args.py --env 一二 --env 三命名空间(env=['one', 'two', 'three'])

您在示例中的 lambda 有点超出了 type kwarg 的预期用例.因此,我建议改为在空白处拆分,因为正确处理 , 实际上在数据中的情况会很痛苦.如果您拆分空间,您将免费获得此功能:

$ python/tmp/args.py --env 一 "hello world" 二 --env 三命名空间(env=['one', 'hello world', 'two', 'three'])

I'd like to make a script that supports an argument list of the form

./myscript --env ONE=1,TWO=2 --env THREE=3

Here's my attempt:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
    '--env',
    type=lambda s: s.split(','),
    action='append',
)
options = parser.parse_args()
print options.env

$ ./myscript --env ONE=1,TWO=2 --env THREE=3
[['ONE=1', 'TWO=2'], ['THREE=3']]

Sure I can fix this in postprocessing:

options.env = [x for y in options.env for x in y]

but I'm wondering if there's some way to get the flattened list directly from argparse, so that I don't have to maintain a list of "things I need to flatten afterwards" in my head as I'm adding new options to the program.

The same question applies if I were to use nargs='*' instead of type=lambda....

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
    '--env',
    nargs='+',
    action='append',
)
options = parser.parse_args()
print options.env

$ ./myscript --env ONE=1 TWO=2 --env THREE=3
[['ONE=1', 'TWO=2'], ['THREE=3']]

解决方案

Edit: Since Python 3.8, the "extend" is available directly in stdlib. If you only have to support 3.8+ then defining it yourself is no longer required. Usage of stdlib "extend" action is exactly the same way as this answer originally described:

>>> import argparse
>>> parser = argparse.ArgumentParser()
>>> _ = parser.add_argument('--env', nargs='+', action='extend')
>>> parser.parse_args(["--env", "ONE", "TWO", "--env", "THREE"])
Namespace(env=['ONE', 'TWO', 'THREE'])


Unfortunately, there isn't an extend action provided in ArgumentParser by default. But it's not too hard to register one:

import argparse

class ExtendAction(argparse.Action):

    def __call__(self, parser, namespace, values, option_string=None):
        items = getattr(namespace, self.dest) or []
        items.extend(values)
        setattr(namespace, self.dest, items)


parser = argparse.ArgumentParser()
parser.register('action', 'extend', ExtendAction)
parser.add_argument('--env', nargs='+', action='extend')

args = parser.parse_args()
print(args)

Demo:

$ python /tmp/args.py --env one two --env three
Namespace(env=['one', 'two', 'three'])

The lambda you have in your example is somewhat outside the intended use-case of the type kwarg. So, I would recommend instead to split on whitespace, because it will be a pain to correctly handle the case where , is actually in the data. If you split on space, you get this functionality for free:

$ python /tmp/args.py --env one "hello world" two --env three
Namespace(env=['one', 'hello world', 'two', 'three'])

这篇关于argparse:展平 action='append' 的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆