如何将argparse参数作为kwargs传递给函数?

46

我有一个定义如下的类

class M(object):
    def __init__(self, **kwargs):
        ...do_something

我有一个argparse.parse_args()的结果,例如:

> args = parse_args()
> print args
Namespace(value=5, message='test', message_type='email', extra="blah", param="whatever")

我希望传递此命名空间的值(除了message_type)以创建类M的实例。我尝试过:

M(args)

但是遇到了一个错误

TypeError: __init__() takes exactly 1 argument (2 given)

我不理解。我如何:
  1. args 列表中删除 message_type 值?
  2. 将值传递,就像我直接键入 M(value=5, message='test', extra="blah", param="whatever") 一样。
1个回答

66
你需要传递vars(args)的结果:
M(**vars(args))

vars() 函数 返回命名空间实例(其__dict__属性)的字典。

M.__init__() 中,只需忽略 message_type 键。


1
这正是我所需要的。谢谢。除了删除某个关键字之外。我需要它被删除,我不能仅仅因为这个问题超出了范围而忽略它。 - Alex
2
我建议使用arg_dict = dict((k,v) for k,v in vars(args).items() if k!="message_type")来避免在使用vars时可能出现的未定义行为。 - Alex
@Alex:vars有什么未定义行为?你可以通过这种方式过滤掉message_type键,但这样做是为了自己的利益,而不是因为vars()可能具有未定义的行为(它并没有)。 - Martijn Pieters
@Alex:我宁愿让M类在面对它不支持的额外关键字参数时更加健壮。 - Martijn Pieters
注意 从vars的文档中可以看到: “返回的字典不应被修改:对应符号表的影响是未定义的。[2]”。 至于您的建议,“M”可以是许多与我在此处所做的完全分离的类之一。这些类可能无法知道某些丰富的关键字(否则可能会出错)。假设这些类不能被修改。 - Alex
1
@Alex:这些值被复制M.__init__参数中,因此原始映射永远不会被修改。如果您需要控制传递的关键字,请使用白名单。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接