argparse:展平action ='append'的结果 [英] argparse: flatten the result of action='append'
问题描述
我想制作一个支持形式参数列表的脚本
I'd like to make a script that supports an argument list of the form
./myscript --env ONE=1,TWO=2 --env THREE=3
这是我的尝试:
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]
但是我想知道是否有某种方法可以直接从argparse中获取扁平化列表,这样我在添加新内容时就不必在脑海中保留我以后需要扁平化的东西"列表.该程序的选项.
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.
如果我使用nargs='*'
而不是type=lambda...
,则会出现相同的问题.
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']]
推荐答案
.如果您只需要支持3.8+,则不再需要自己定义.使用stdlib"extend"操作的方式与最初描述的答案完全相同:
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'])
不幸的是,默认情况下ArgumentParser
中没有提供extend
操作.但是注册一个不是很困难:
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)
演示:
$ python /tmp/args.py --env one two --env three
Namespace(env=['one', 'two', 'three'])
示例中的lambda
稍微超出了type
kwarg的预期用例.因此,我建议改为在空白处进行分割,因为正确处理,
实际上在数据中的情况将很痛苦.如果您在空间上划分空间,则可以免费获得此功能:
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屋!