为什么使用**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}
请记住 args
和 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}
请记住 args
和 kwargs
是约定,而不是规则。您可以使用不同的名称,重要的是 *
和 **
。