Вопрос проверяет понимание ограничений кэширования и способов приведения аргументов к хэшируемому виду.
Если аргументы функции нехэшируемые (например, списки или словари), их нельзя напрямую использовать как ключ кэша. Обычно их преобразуют в хэшируемый вид: список в кортеж, словарь в frozenset или сериализованную строку. В более сложных случаях используют кастомную функцию нормализации аргументов. Главное — обеспечить стабильное представление аргументов.
Кэш обычно реализуется на основе словаря, а ключи словаря должны быть хэшируемыми. Поэтому аргументы функции необходимо преобразовать в хэшируемую форму.
Приведение к неизменяемым типам
Чаще всего используется преобразование:
list → tuple
set → frozenset
dict → tuple(sorted(dict.items()))
Пример:
def make_hashable(obj):
if isinstance(obj, list):
return tuple(make_hashable(i) for i in obj)
if isinstance(obj, dict):
return tuple(sorted((k, make_hashable(v)) for k, v in obj.items()))
return obj
Сериализация аргументов
Можно преобразовать аргументы в строку:
import json
key = json.dumps(args, sort_keys=True)
Этот подход удобен, но медленнее.
Ограничение интерфейса
Иногда проще явно требовать, чтобы аргументы функции были хэшируемыми.
При преобразовании аргументов нужно обеспечить:
детерминированность
одинаковый ключ для одинаковых значений
независимость от порядка словарей
Если аргументы нехэшируемые, их необходимо нормализовать в неизменяемую форму или сериализовать. Это стандартная практика при реализации универсальных кэшей.