2014-04-01 64 views
2

爲了說明我創建了一個簡單的例子問題:爲什麼setdefault在設置密鑰時評估默認值?

#!/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... 

函數被一次又一次地調用。怎麼了?

+0

無論函數'setdefault'是否使用它,參數總是會被創建。 –

回答

7

這個問題不在setdefault,但在Python(以及大多數語言)的一般原則中,所有參數必須在函數調用之前進行評估。也就是說,即使在Python檢查鍵是否在字典中之前,它也需要知道鍵和默認值的值:並且由於默認值是函數的結果,因此必須先調用該函數。

+0

所以在最後我認爲解決的辦法是替代 '回報self.cache.setdefault(self.name,get_age())' 與 '回報self.cache.get(self.name,FALSE)或自.cache.setdefault(self.name,get_age())' – Andrei