【问题标题】:Why can't I pass a direct reference to a dictionary value to a function?为什么我不能将字典值的直接引用传递给函数?
【发布时间】:2009-05-13 00:25:53
【问题描述】:

今天早些时候我问了question 关于将字典值传递给函数。虽然我现在明白如何完成我试图完成的事情,但为什么问题(没有被问到)从未得到回答。所以我的跟进是为什么我不能

def myFunction(newDict['bubba']):
    some code to process the parameter

仅仅是因为解析器规则不允许这样做吗?我在 Google 上搜索了 +Python +function +“允许的参数”,但没有发现任何有用的信息,因此我将不胜感激。

我过于简单化了正在发生的事情。我有一本结构类似的字典

myDict={outerkey1:(innerkey1:value,innerkey2:value,. . .innerkeyn:value),outerkey2:(innerkey1:value,innerkey2:value,. . .innerkeyn:value),. . .}

正如我所说,我知道如何做我想做的事——我得到了一个非常有帮助的答案。但我开始想知道为什么

 def myFunction(outerkey,myDict[outerkey]):

给出了一个语法错误,我很好地意识到它必须是一个解析问题。

【问题讨论】:

    标签: python function dictionary parameters


    【解决方案1】:

    是的,解析器将拒绝此代码。

    参数列表用于函数定义中,将函数内的标识符绑定到调用时从外部传入的参数。

    由于newDict['bubba'] 不是有效标识符,这没有任何意义——您需要将其作为调用参数而不是函数参数提供,因为函数参数只能是标识符。

    因为您似乎对formal grammar 感兴趣,所以这里是相关部分:

    funcdef ::= 
                 [decorators] "def" funcname "(" [parameter_list] ")"
                  ":" suite
    
    parameter_list ::= 
                     (defparameter ",")*
                    (~~"*" identifier [, "**" identifier]
                     | "**" identifier
                     | defparameter [","] )
    
    defparameter ::= 
                 parameter ["=" expression]
    
    identifier ::= 
                 (letter|"_") (letter | digit | "_")*
    

    实际上,您尝试用作标识符的构造是订阅:

    subscription ::= 
                 primary "[" expression_list "]"
    

    【讨论】:

    • newDict['bubba'] 不是一个有效的标识符我想学习如何阅读语法将有助于理解这一点。当我从这条线开始时,我决定它应该可以工作,因为当调用函数时 newDict['bubba'] 引用了我希望函数作用的东西。解决方案是在调用中的引用前面使用**,并在定义中的名称前面使用**,正如其他人所描述的那样,但我不明白(现在只在肤浅的层面上做),直到你回答。希望当我感到无聊并阅读语法时,我会学到更多,再次感谢
    • 在 Python 中,标识符(对象的名称)中只能包含字母、数字和下划线。如果语法允许newDict['bubba'] 作为命名对象的符号,则很难区分命名对象的符号和列表/字典上的下标操作。另外,如果您可以使用newDict['bubba'] 作为标识符,那会令人困惑,因为newDict 不是一个有效的标识符,即使它看起来像是您可以索引的东西。
    • 标识符(对象的名称)只能包含字母、数字和下划线,所以这确实是我今天问题的症结所在
    • 是的!为了提高可读性,Python 允许在其标识符中使用非常有限的字符集。
    【解决方案2】:

    看起来您可能对函数的定义调用该函数感到困惑。举个简单的例子:

    def f(x):
        y = x * x
        print "x squared is", y
    

    这个函数本身不做任何事情(即它不打印任何东西)。如果将其放入源文件并运行它,则不会输出任何内容。但是如果你添加:

    f(5)
    

    您将得到“x 平方为 25”的输出。当 Python 遇到函数名后跟 actual 参数时,它会将这些实际参数的值替换为函数定义中的 formal 参数。在这种情况下,形参称为x。然后 Python 运行函数 f 并将 x 的值设为 5。现在,最大的好处是您可以再次使用相同的函数并使用不同的值:

    f(10)
    

    打印“x 的平方为 100”。

    我希望我已经正确理解了你的困难的根源。

    【讨论】:

    • 不,我想我理解我想定义我的函数和稍后在 myDict 中键入的区别:result=myFunction(outerKey,myDict[innerKey]) 正如我所说,我得到了一个我想要的好答案知道为什么我原来的方法不起作用
    【解决方案3】:

    您只能传递对对象的引用。

    a = { 'a' : 123, 'b' : [ 1, 2, 3 ] }
    
    def f(dictionary_value):
        dictionary_value.append(4)
    
    f( a['b'] )
    

    做你期望的。字典元素a['b']“通过引用”传递给函数f,该函数更新字典元素。

    【讨论】:

    • 这很有趣,看起来比我今天使用的解决方案更简单,而且很有效。很酷,所以我可以接受两个答案吗?
    • 他正在传递一个引用类型(一个列表)。如果你以这种方式传递 a['a'],执行 dictionary_value += 2 不会影响 a['a']。了解值类型和引用类型之间的区别很重要!
    • 一切都是参考。 “引用类型”和“值类型”之间没有有用的区别。但是,有些类型是不可变的。不变性使它们看起来像 Java 或 C++ 中的“值”类型。
    • 对,但是你必须开始解释标识符绑定——我假设大多数人来自语言,“按值”和“按引用”的想法只会在他们的脑海中以正确的方式点击。我可能应该停止这样做。 :-)
    • 我是从 SAS 来的,在大型机上学过——那些是什么 :)
    猜你喜欢
    • 2012-01-15
    • 2021-02-24
    • 2023-03-16
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 2018-09-03
    相关资源
    最近更新 更多