【问题标题】:Why is the parentheses at end of return statement used in code below and why does if I don'y use parentheses it return address?为什么在下面的代码中使用 return 语句末尾的括号,为什么如果我不使用括号它返回地址?
【发布时间】:2018-08-12 10:05:13
【问题描述】:

示例:为什么 dictuse1 返回值但 dictuse2 返回地址如下所示

def dictuse1(operator,x,y):
    return{
    'add':lambda:x + y,
    'sub':lambda:x - y,
    'mul':lambda:x * y,
    'div':lambda:x / y,
    }.get(operator,lambda:None)()
def dictuse2(operator,x,y):
    return{
    'add':lambda:x + y,
    'sub':lambda:x - y,
    'mul':lambda:x * y,
    'div':lambda:x / y,
    }.get(operator,lambda:None)     #No parentheses here compared to previous function
d = dictuse1('add',8,9)
print(d)      #return 17
a = dictuse2('a',5,4)
print(a)      #returns:<function dictuse.<locals>.<lambda> at 0x7f30d23f3ea0>

【问题讨论】:

  • 顺便说一句,使用operator 作为变量名不是一个好主意,因为它是标准模块的名称。顺便说一句,该模块在此代码中很有用,因为它定义了您使用 lambda 定义的函数。
  • @PM2Ring 我不确定operator 在这里是否真的有帮助,因为这些函数都是xy 参数上的无效闭包,所以你必须写类似的东西functools.partial(operator.add, x, y),这并没有您通常从模块中获得的好处。但总的来说,这绝对是个好建议。
  • @abarnert 啊,好点子。

标签: python python-3.x switch-statement


【解决方案1】:

括号与return无关;他们在那里调用一个函数,就像你总是调用一个函数一样。

让我们把它分解成更易读的形式:

function_table = {
    'add': lambda: x + y,
    'sub': lambda: x - y,
    'mul': lambda: x * y,
    'div': lambda: x / y,
}

到目前为止,一切都很好:这只是一个将字符串映射到函数的字典,因此您可以按名称查找函数。

default_function = lambda: None

这只是一个你可以调用并返回None的函数。

function = function_table.get(operator, default_function)

这只是在字典中查找一个值。 d.get(key, default) 给你d[key] 如果该键有值,或者default 如果没有。

所以,现在functionadd 函数lambda: x+y,或默认lambda: None,或其他三个中的任何一个,但无论是哪个,它都是一个不带参数的函数。所以我们可以称之为它。这就是括号的来源:

value = function()

现在我们只返回那个值:

return value

如果你去掉括号,你就不会调用函数并返回它给你的值,你只是返回它。因此,不是返回5None,而是返回一个函数对象。如果您尝试将其打印出来,它可能会显示类似&lt;function '&lt;lambda&gt;' at 0x12345788&gt; 的内容,但它说什么并不重要;它告诉你的是你正在打印的东西是一些函数,它没有名字,因为你用lambda而不是def定义了它。

【讨论】:

    【解决方案2】:

    尝试在一些有意义的部分上拆分这样的单行。

    def dictuse1(operator, x, y):
        # Stores mapping from operator names (strings) 
        # to op implementations (functions == lambdas)
        optable = {
            'add': lambda: x + y,
            'sub': lambda: x - y,
            'mul': lambda: x * y,
            'div': lambda: x / y,
        }
    
        # Define a default op
        noop = lambda: None
    
        # Take the function by op name
        op = optable.get(operator, noop)
    
        # Exectute it and return a returning value of that function.
        return op()  # remove () and you have a dictuse2 here.
    

    dictuse1dictuse2 之间的唯一区别是最后一个返回函数而不是调用该函数的结果。

    【讨论】:

      【解决方案3】:

      因为在 Python 中一切都是对象。这包括整数、浮点数、字符串、其他类的实例、类本身函数

      第一个函数从字典中检索一个函数或使用默认值并调用它,返回调用的结果(在你的情况下是一个数字)。

      第二个返回函数本身

      括号是函数调用的符号:例如(lambda x, y: x + y)(1, 2),调用函数并返回1 + 2 == 3。如果你去掉括号,你会得到一个函数对象。

      【讨论】:

        【解决方案4】:

        因为如果您要查找的键不在字典中,则字典上的 get 方法返回默认值,当您传递不在字典中的 a 时,它返回 lambda:None 这是一个匿名函数和执行你必须用括号调用的函数

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-05-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-02-08
          • 1970-01-01
          • 2017-10-27
          相关资源
          最近更新 更多