Причина, по которой кеширование работает, заключается в концепции, называемой закрытием. Вы правильно понимаете, что локальные переменные удаляются после выхода из функции, но переменные, используемые здесь для кеширования, не являются локальными для внутренней функции.
Если вы используете _logged_cached
декоратор для функции, функция будет по существу заменить вложенной функцией wrapper
. Эта wrapper
функция при возврате становится закрытием (функциональным объектом), который запоминает нелокальные переменные в охватывающей области. Таким образом, у него будет отображение, которое запоминает переменные called
и ret
. Каждый раз, когда вы вызываете объект функции (декорированную функцию), внутренняя область видимости будет иметь called
и ret
, доступные для использования.
Обычно они будут доступны только для чтения во внутренней функции, но используя ключевое слово nonlocal
, внутренняя функция действительно может изменять / обновлять значения переменных called
и ret
в закрытии. Таким образом, упомянутое нами ранее отображение, сохраненное в объекте функции, обновляет свои значения, и каждый последующий вызов декорированной функции будет использовать те же значения.