Там могут быть более простые способы делать то, что вы хотите -
Тем не менее, я однажды написал универсальный «ленивый декоратор» для универсальных функций, который делает именно то, что вы просите - воспринимать это сложнее именно потому, что он будет работать практически для любого типа объектов, возвращаемых функциями.
Основная идея такова: для данного существующего объекта Python фактически не «использует» его значение, но для вызова одного из методов «dunder» (magic double «__») в классе объекта -
будь то для его представления (вызывает либо __repr__ __str__ __unicode__
), получения из него атрибутов, совершения вызовов, использования его в качестве оператора в арифметической операции и так далее.
Итак, этот декоратор, когда вызывается функция, в основном сохраняет параметры и ожидает вызова любого из этих магических методов, после чего он выполняет вызов originall и кэширует возвращаемое значение -
Код соруса здесь:
https://bitbucket.org/jsbueno/metapython/src/f48d6bd388fd/lazy_decorator.py