【问题标题】:Why does the key 'kwargs' appear when using **kwargs?为什么使用 **kwargs 时会出现键 'kwargs'?
【发布时间】:2021-08-09 20:48:49
【问题描述】:

为什么在我运行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'}}

【问题讨论】:

  • 这能回答你的问题吗? Passing a list of kwargs? 使用 my_class = MyClass(**test_kwargs)
  • 如果你定义了def __init__(self, kwargs): 没有**,你会得到预期的结果。
  • @paxdiablo 你为什么重新打开这个? OP 说副本回答了他们的问题。
  • @JohnKugelman:我投票决定重新开放,因为问题本身与提议的问题并不重复。另一个问题是如何将kwargs 传递给另一个函数,这个函数正在寻找信息,说明为什么这样做会涉及额外的间接级别。相关,是的,但在我看来不是重复的 - 重复关闭的文本是“这个问题之前已经被问过并且已经有了答案”。

标签: python keyword-argument


【解决方案1】:

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

如果您想将字典视为 kwargs,则需要使用 my_class = MyClass(**test_kwargs) 调用

【讨论】:

    【解决方案2】:

    这是因为**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 是约定,而不是规则。您可以使用不同的名称,重要的是***

    【讨论】:

      【解决方案3】:

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

      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'}
      

      【讨论】:

        猜你喜欢
        • 2017-03-26
        • 2019-09-14
        • 2013-09-26
        • 1970-01-01
        • 1970-01-01
        • 2021-11-26
        • 2015-10-19
        • 2012-05-29
        • 2018-10-18
        相关资源
        最近更新 更多