Почему 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...

Функция вызывается снова и снова. В чем дело?

1 ответ

Решение

Проблема не в setdefault, но в общем принципе в Python (как и в большинстве языков) все аргументы должны быть оценены перед вызовом функции. То есть, даже до того, как Python проверит, находится ли ключ в словаре, ему нужно знать значение ключа и значение по умолчанию: и поскольку значение по умолчанию является результатом функции, эта функция должна вызываться первой,

Другие вопросы по тегам