kwargs 是按值传递还是解压 dict 复制数据?
Does kwargs is passed by value or does unpacking dict copies data?
最好用例子来说明我的问题。
假设我有以下代码:
from pprint import pprint
def remove(**kwargs):
del kwargs['first']
d = {'first': {'x': 10}, 'second': {'a': '1'}}
logger.debug(f"{pprint(d)}")
remove(**d)
logger.debug(f"{pprint(d)}")
输出为:
{'first': {'x': 10}, 'second': {'a': '1'}}
{'first': {'x': 10}, 'second': {'a': '1'}}
即 'first'
键仍然存在,就好像我们已经通过值 传递了我们的字典 d ,所以在函数内部对它的任何更改对于来电者。
我期待我的 d 被引用传递,也就是说我的字典被修改了,我期待看到以下输出:
{'first': {'x': 10}, 'second': {'a': '1'}}
{'second': {'a': '1'}}
为什么我错了?
您没有将 d
传递给函数,而是将 d
中的值扩展为函数的命名参数。在有问题的函数中,您然后再次将它们作为字典接收,但是如果您将值作为命名参数传递或接收值作为命名参数,那么它们将不会分别来自或最终出现在字典中。
例如如果您可以修改 **kwargs
的来源,在这种情况下这意味着什么?
remove(first={'x': 10}, second={'a': '1'})
这真的没有意义。
如果你想完成函数名所暗示的动作,你会想直接传递一个字典对象作为参数;那么它将通过引用和函数内的修改将按您期望的那样工作。
def remove(dictarg):
del dictarg['first']
d = {'first': {'x': 10}, 'second': {'a': '1'}}
remove(d)
pprint(d)
>>> {'second': {'a': '1'}}
最好用例子来说明我的问题。 假设我有以下代码:
from pprint import pprint
def remove(**kwargs):
del kwargs['first']
d = {'first': {'x': 10}, 'second': {'a': '1'}}
logger.debug(f"{pprint(d)}")
remove(**d)
logger.debug(f"{pprint(d)}")
输出为:
{'first': {'x': 10}, 'second': {'a': '1'}}
{'first': {'x': 10}, 'second': {'a': '1'}}
即 'first'
键仍然存在,就好像我们已经通过值 传递了我们的字典 d ,所以在函数内部对它的任何更改对于来电者。
我期待我的 d 被引用传递,也就是说我的字典被修改了,我期待看到以下输出:
{'first': {'x': 10}, 'second': {'a': '1'}}
{'second': {'a': '1'}}
为什么我错了?
您没有将 d
传递给函数,而是将 d
中的值扩展为函数的命名参数。在有问题的函数中,您然后再次将它们作为字典接收,但是如果您将值作为命名参数传递或接收值作为命名参数,那么它们将不会分别来自或最终出现在字典中。
例如如果您可以修改 **kwargs
的来源,在这种情况下这意味着什么?
remove(first={'x': 10}, second={'a': '1'})
这真的没有意义。
如果你想完成函数名所暗示的动作,你会想直接传递一个字典对象作为参数;那么它将通过引用和函数内的修改将按您期望的那样工作。
def remove(dictarg):
del dictarg['first']
d = {'first': {'x': 10}, 'second': {'a': '1'}}
remove(d)
pprint(d)
>>> {'second': {'a': '1'}}