示例:为什么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>
答案 0 :(得分:4)
括号与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
。
因此,现在function
是add
函数lambda: x+y
或默认lambda: None
或其他三个函数中的任何一个,但无论是哪个函数,它都是一个函数没有参数。所以我们可以称之为。这是括号的所在位置:
value = function()
现在我们只返回该值:
return value
如果省略了括号,则不会调用该函数并返回它给您的值,而只是返回它。因此,您无需取回5
或None
,而是取回一个函数对象。如果您尝试将其打印出来,也许它会说类似<function '<lambda>' at 0x12345788>
,但它的内容并不重要;它只是告诉您正在打印的内容是某种功能,它没有名称,因为您使用lambda
而不是def
定义了它。
答案 1 :(得分: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.
dictuse1
和dictuse2
之间的唯一区别是最后一个返回函数而不是调用该函数的结果。
答案 2 :(得分:1)
因为在Python中,所有内容都是一个对象。其中包括整数,浮点数,字符串,其他类的实例,类本身和函数。
第一个函数从字典中检索一个函数或使用默认值并调用,返回调用结果(在您的情况下为数字)。
第二个返回函数本身。
括号是函数调用的表示法:例如,(lambda x, y: x + y)(1, 2)
调用函数并返回1 + 2 == 3
。如果删除括号,则会得到一个函数对象。
答案 3 :(得分:0)
因为如果要查找的键不在字典中,则字典上的get
方法将返回默认值,当您传递不在字典中的a
时,它将返回lambda:None
这是一个匿名函数,要执行必须使用括号调用的函数