我正在尝试将字典作为参数传递,并且看到如下所示的两种方法,这使得它在传递**时保持字典值不变
def dict_test1(**d):
d['a'] = '10'
def dict_test2(d):
d['a'] = '10'
d = {'a': '1'}
dict_test1(**d)
print d
dict_test2(d)
print d
输出:
{'a': '1'}
{'a': '10'}
答案 0 :(得分:3)
只是(**d)
创建了一个新的dict
,而(d)
保留了对旧def dict_test1(**d):
print d is d_global # False
def dict_test2(d):
print d is d_global # True
d_global = {'a': '1'}
dict_test1(**d_global )
dict_test2(d_global)
的引用:
"/data/logs/*.log" {
daily
rotate 5
compress
missingok
notifempty
prerotate
echo "file name is: <file_name>"
endscript
}
答案 1 :(得分:0)
要了解正在发生的事情,请考虑以下情况:
>>> def test1(**d):
... print(d)
>>> test1(spam=10)
{'spam': 10}
{'spam': 10}
来自哪里?简单:**d
只是打包所有不匹配任何命名参数的关键字参数,无论它们来自何处,都会转换为新的字典,并将该字典赋予d
。
现在请查看参数方面的**
:
>>> def test2(spam, eggs):
... print(spam, eggs)
>>> d = {'eggs': 10, 'spam': 20}
>>> test2(**d)
20 10
因此,Python正在将**d
扩展为一堆独立的关键字参数,这些参数与参数完全匹配实际的单独关键字参数。
最后,双方都是:
>>> def test3(spam, eggs, **d):
... print(spam, eggs)
... print(d)
>>> d = {'spam': 10, 'cheese': 20}
>>> test3(eggs=30, **d)
10 30
{'cheese': 20}
因此,Python将**d
参数扩展为两个单独的关键字参数,将它们与普通关键字参数eggs=30
放在一起,将它们与参数spam
和{{1}匹配在eggs
参数中将任何剩余部分存储在新的dict中。
这一点在the tutorial中松散地解释,在the reference中更严格地解释。
在定义上有一个**d
参数并且在调用上有一个**d
参数这个事实真的没什么特别之处;他们不必以任何方式相互对应。
有些人认为不幸的是Python在调用中的定义和参数解包中使用与变量参数参数相同的语法,同样在调用的定义和关键字参数中使用相同的默认参数值语法。但是,虽然这是第一次碰到它时令人困惑,但一旦你明白,它就很容易记住和阅读。使用**d
与...args
之类的语法区分这两种语言的其他语言似乎并不那么令人困惑。