gpt4 book ai didi

python - 从 argparse 解包参数

转载 作者:太空狗 更新时间:2023-10-29 17:26:53 26 4
gpt4 key购买 nike

我一直在编写一些命令行 python 程序并使用 argparse 来完成它。我一直在按如下方式构建我的代码。

def main(arg1, arg2):
# magic
pass

if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('arg1')
parser.add_argument('arg2')

args = parser.parse_args()

main(args.arg1, args.arg2)

不得不调用 arg1arg2 3 次真的 super 烦人。我知道必须做两次。

有什么方法可以将 parse_args 函数返回的命名空间当作元组处理吗?或者更好的是作为可选参数的元组和字典并进行解包?

if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('arg1')
parser.add_argument('arg2')
parser.add_argument('--opt-arg', default='default_value')

args, kwargs = parser.magic_method_call_that_would_make_my_life_amazing()

# I get goosebumps just thinking about this
main(*args, **kwargs)

最佳答案

https://docs.python.org/3/library/argparse.html#the-namespace-object

This class is deliberately simple, just an object subclass with a readable string representation. If you prefer to have dict-like view of the attributes, you can use the standard Python idiom, vars():

>>>
>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

请注意,从 optparseargparse 的一大进步,或至少是变化之一是位置参数(例如您的参数)被视为与可选参数相同。它们都出现在 args Namespace 对象中。在 optparse 中,positionals 只是解析定义选项的遗留物。您可以通过省略参数并使用 parse_known_argsargparse 中获得相同的效果:

parser = argparse.ArgumentParser()
args, extras = parser.parse_known_args()

args 现在是一个命名空间,extras 是一个列表。然后你可以调用你的函数:

myfoo(*extras, **vars(args))

例如:

In [994]: import argparse
In [995]: def foo(*args, **kwargs):
.....: print(args)
.....: print(kwargs)
.....:
In [996]: parser=argparse.ArgumentParser()
In [997]: parser.add_argument('-f','--foo')
Out[997]: _StoreAction(option_strings=['-f', '--foo'], dest='foo', nargs=None, const=None, default=None, type=None, choices=None, help=None, metavar=None)
In [998]: args,extras = parser.parse_known_args(['-f','foobar','arg1','arg2'])
In [999]: args
Out[999]: Namespace(foo='foobar')
In [1000]: extras
Out[1000]: ['arg1', 'arg2']
In [1001]: foo(*extras, **vars(args))
('arg1', 'arg2')
{'foo': 'foobar'}

同样的 argparse 段落表明您可以定义自己的 Namespace 类。定义一个行为类似于字典(用作 **args)和 namespace 的并不难。所有 argparse 都需要它与 getattrsetattr 一起工作。

In [1002]: getattr(args,'foo')
Out[1002]: 'foobar'
In [1004]: setattr(args,'bar','ugg')
In [1005]: args
Out[1005]: Namespace(bar='ugg', foo='foobar')

另一个标准的 Python 功能让我可以将 vars(args) 作为元组传递:

In [1013]: foo(*vars(args).items())
(('foo', 'foobar'), ('bar', 'ugg'))
{}

对于去年一月的类似回答:https://stackoverflow.com/a/34932478/901925

Neatly pass positional arguments as args and optional arguments as kwargs from argpase to a function

在那里我给出了关于如何在解析后将“位置”与“可选”分开的想法。


这是一个自定义命名空间类,在其 API 中包含一种将自身作为字典返回的方法:

In [1014]: class MyNameSpace(argparse.Namespace):
......: def asdict(self):
......: return vars(self)
......:
In [1015]: args = parser.parse_args(['-f','foobar'], namespace=MyNameSpace())
In [1016]: args
Out[1016]: MyNameSpace(foo='foobar')
In [1017]: foo(**args.asdict())
()
{'foo': 'foobar'}

另一个想法 - 使用多个 nargs (2,'*','+') 之一作为位置参数。然后,在将其传递给您的函数时,您只需输入一个名称即可。

parser.add_argument('pos',nargs='+')
args = ...
args.pos # a list, possibly empty
foo(*args.pos, **vars(args))

关于python - 从 argparse 解包参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35822477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com