【Python】**kwargs和takes 1 positional argument but 2 were given

Python的函数定义中可以在参数里添加kwargs——简单来说目的是允许 添加不定参数名称的参数,并作为 字典传递参数。但前提是——你必须提供 参数名**。

例如下述情况:

1 class C():
2     def __init__(self, **kwargs):
3         print(kwargs)

有如下输入:

In [48]: c = C()
{}

In [49]: c = C(a = 1)
{'a': 1}

这一切都符合常理。但是当我使用一个字典传递的时候:

In [50]: c = C({'a': 1})

我一开始以为是__init__太娇气了,换成一般办法:

1 In [51]: class C():
2     ...:     def f(self, **kwargs):
3     ...:         print(kwargs)
4     ...:
In [52]: c = C()

In [53]: c.f({'a': 1})

TypeError: f() takes 1 positional argument but 2 were given

包括定义在__main__下的函数也是如此:

In [54]: def f1(**kwargs):
    ...:     print(kwargs)
    ...:

In [56]: f1({'a': 1})

TypeError: f1() takes 0 positional arguments but 1 was given

但是当我在f1参数前加一个 参数名

1 In [57]: f1(b = {'a': 1})
2 {'b': {'a': 1}}

问题立刻解决。

思考:

我们在先前的错误尝试中,一直传入的是个 单纯的字典。虽然kwargs提供将参数转成字典的功能,但是 直接传入字典并不会使其理解成参数。实质上Python解释器认为我们输入的是 作为参数值的字典,而并未携带 参数名称,而Python函数机制中”固定名称”的参数应写在kwargs的前面,因此误以为我们传入了一个”固定名称”参数,事实上我们先前的定义中并未加入”固定名称”参数,所以报错 takes 1 positional arguments but 2 was given

如果真的要传入字典怎么办呢?这就简单了,直接把 *kwargs*改成 kwargs**即可:

1 In [58]: class C():
2     ...:     def __init__(self, kwargs):
3     ...:         print(kwargs)
4     ...:
5
6 In [59]: c = C({'a': 1})
7 {'a': 1}

这次经历使我加深了对**kwargs特殊参数的理解。以后的学习更要注意细节!

Original: https://www.cnblogs.com/littleye233/p/11618990.html
Author: 小叶Little_Ye
Title: 【Python】**kwargs和takes 1 positional argument but 2 were given

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/606340/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球