为什么在设置键时,setdefault会评估默认值?

5
为了说明问题,我创建了一个简单的示例:
#!/usr/bin/env python

class Person():
    def __init__(self):
        self.cache = {}

    def get_person_age(self):
        def get_age():
            print "Calculating age..."
            return self.age
        print self.cache
        return self.cache.setdefault(self.name, get_age())

    def set_person(self, name, age):
        self.name = name
        self.age = age


p = Person()
p.set_person('andrei', 12)

for k in range(0, 5):
    p.get_person_age()

我的期望是,一旦设置了缓存,函数get_person_age就不会再被调用。但事实并非如此:

$ python cache_test.py 
{}
Calculating age...
{'andrei': 12}
Calculating age...
{'andrei': 12}
Calculating age...
{'andrei': 12}
Calculating age...
{'andrei': 12}
Calculating age...

函数被反复调用,出了什么问题?


无论函数 setdefault 是否使用它,参数都将被创建。 - Mark Ransom
1个回答

10
问题不在于`setdefault`,而是Python(以及大多数语言)的一个普遍原则,即在调用函数之前必须评估所有参数。也就是说,即使在Python检查键是否在字典中之前,它也需要知道键和默认值的值:由于默认值是函数的结果,所以必须先调用该函数。

所以最终我认为解决方案是将 return self.cache.setdefault(self.name, get_age()) 替换为 return self.cache.get(self.name, False) or self.cache.setdefault(self.name, get_age()) - Andrei

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接