【问题标题】:Weird .get() default [duplicate]奇怪的 .get() 默认 [重复]
【发布时间】:2021-08-27 22:59:29
【问题描述】:

我一直假设如果字典中存在键,则永远不会调用 myDict.get('key', default_value) 表达式中的默认值。但是,我最近发现它以某种方式存在。例如,考虑代码

def doSomething(): 
    print('Done')
    return 'Another value'

myDict = {'key': 'value'}
print(myDict.get('key', doSomething()))

人们会认为,由于 myDict 中存在 key,那么 myDict.get('key', doSomething()) 唯一要做的就是返回 value,因此, doSomething 函数永远不会被调用。然而情况并非如此,在 python 中运行此代码当前输出:

Done
value

我的问题是:为什么会这样? key存在时,为什么default_value没有被完全忽略?

并且可以做些什么来改变这一点,即当 key 存在时不调用 default_value

【问题讨论】:

  • get 是一个函数。像所有 python 函数一样,参数将在将它们传递给函数之前进行评估。这并不取决于get——它只是在评估后接收传入的值。
  • get 方法不是某种有条件地评估其参数的宏。它是一种方法,它是一种函数。调用时,它的所有参数都被评估并传递给函数。这是 Python 的基础。
  • 如果你不希望函数被评估,那么你可以传递函数对象myDict.get('key', doSomething)。但是,除非您的有效值也是可调用函数,否则不确定其用例

标签: python python-3.x


【解决方案1】:

这是因为字典的get 方法不接受作为Java's computeIfAbsent 的回调,而是接受一个值。如果你不希望它被调用,你可以使用三元表达式:

print(doSomething() if myDict.get('key') is None else myDict.get('key'))

【讨论】:

  • 这还不叫doSomething吗?
  • @Mark 好的,但正如写的那样,当值确实存在时,它仍然会打印 Done 和 None
  • @OneCricketeer Python 有一个 if...else 表达式,例如v1 if cond else v2。在此示例中,表达式 v1 仅在 cond 为真时计算,v2 仅在 cond 为假时计算。你可以了解他们here
  • @OneCricketeer,是的,你是对的,它会打印doSomething 的返回值,这是无,但如果 OP 的代码按照他们希望的方式工作,它似乎也会如此。
  • @Mark 这不是语法糖。它是一个表达式,与您展示的相反,它是一个不能在表达式上下文中使用的语句。
【解决方案2】:

按照您编写的方式,doSomething() 被执行之前 myDict.get() 被调用,它的返回值(隐含为None,因为没有返回语句)作为默认值传入。

print(myDict.get('key', doSomething()))
# evaluates to
print(myDict.get('key', None))
# evaluates to
print('value')

根据经验,将表达式作为函数参数传递总是首先计算表达式,然后再将其结果作为该参数传递。

get() 无法在不存在的键上运行单独的函数。如果你传入一个 lambda 作为默认值,你会得到相同的 lambda 作为默认值,未调用。

【讨论】:

  • 该问题与 doSomething() 的返回值无关,因为这仅在密钥不在字典中的情况下才相关。但是感谢您的澄清,“将表达式作为函数参数传递将始终首先评估表达式”是我需要实现的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多