为什么使用**kwargs时会出现'kwargs'键?

Why does the key 'kwargs' appear when using **kwargs?

为什么我运行test_func()时出现{'kwargs':{'1':'a', '2':'b'}}? 我本来希望这样打印:{'1':'a', '2':'b'}.

代码:

class MyClass:
    def __init__(self, **kwargs):
        self.kwargs = kwargs

    def test_func(self):
        print(self.kwargs)

test_kwargs = {'1':'a', '2':'b'}
my_class = MyClass(kwargs=test_kwargs)
my_class.test_func()

输出:

{'kwargs': {'1': 'a', '2': 'b'}}

首先,让我们简化您的示例。由于您的问题与 类 无关,我们可以使用全局函数代替:

def test_kwargs(**kwargs):
    print(kwargs)

其次,我们换个名字:

test_kwargs = {'1':'a', '2':'b'}
test_kwargs(test=test_kwargs)

输出:

{'test': {'1': 'a', '2': 'b'}}

现在我们看到名称 test 来自函数 call 中给出的名称,而不是函数定义。这就是您的原始代码中发生的情况。

以下是一些可能有助于澄清某些事情的其他示例:

您可以传递多个参数,每个参数都有自己的名称:

test_kwargs(a=1, b=2)

输出:

{'a': 1, 'b': 2}

或者您可以将字典扩展为函数的关键字参数:

test_kwargs(**test_kwargs)

输出:

{'1':'a', '2':'b'}

这是因为您通过将字典作为值传递给名为 kwargs 的 1 个关键字参数来初始化实例。

如果你想以 kwargs 的形式查看字典,你需要使用 my_class = MyClass(**test_kwargs)

调用

这是因为 **kwargs 自动 收集 剩余的(未使用的)命名参数并将它们放入字典中,与 *args 收集非常相似未使用的未命名(位置)参数到元组(a).

它的目的是处理像这样的事情:

my_class = MyClass(a=1, b=2)

这可能是您尝试要做的事情。

你在问题中所做的方式将导致字典的键 kwargs 引用字典,因为它将创建一个以参数名称 kwargs 为键的字典 - 即正是你所看到的。


(a) 您可以在以下记录中看到此行为:

Python 3.9.0 (default, Oct 12 2020, 02:44:01)
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def fn(one, two, *args, **kwargs):
...     print(one)
...     print(two)
...     print(args)
...     print(kwargs)
...
>>> fn(1, 2, 3, 4, 5, six=6, seven=7)
1
2
(3, 4, 5)
{'six': 6, 'seven': 7}

请记住 argskwargs 是约定,而不是规则。您可以使用不同的名称,重要的是 ***