【问题标题】:Python dictionary argument passing methodsPython 字典参数传递方法
【发布时间】:2018-06-13 21:24:28
【问题描述】:

我正在尝试将字典作为参数传递,并看到如下所示的 2 种方法,是什么使它在使用 ** 传递时保持字典值不变

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

【问题讨论】:

    标签: python dictionary methods arguments


    【解决方案1】:

    只是(**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) 
    

    【讨论】:

      【解决方案2】:

      要了解发生了什么,请考虑以下案例:

      >>> 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 放在一起,将它们与参数 spameggs 匹配,并将任何剩余部分存储在**d 参数中的新字典。


      the tutorial 对此进行了粗略的解释,the reference 对此进行了更严格的解释。

      事实上,你在定义上有一个**d 参数并在调用上有一个**d 参数这一事实并没有什么特别之处;它们不必以任何方式相互对应。

      有些人认为不幸的是,Python 对定义中的可变参数参数和调用中的参数解包使用相同的语法,并且对定义中的默认参数值和调用中的关键字参数使用相同的语法。但是,虽然当你第一次遇到它时会感到困惑,但一旦你理解了,它就很容易记住和阅读。其他用 ...argsseq... 等语法区分两者的语言最初似乎并没有减少混淆。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多