Я не видел установленного способа memoize функции, которая принимает аргументы ключевого слова, то есть что-то типа
def f(*args, **kwargs)
поскольку, как правило, memoizer имеет dict
для кэширования результатов для заданного набора входных параметров, а kwargs
является dict
и, следовательно, недоступен. Я пробовал, после обсуждения здесь, используя
(args, frozenset(kwargs.items()))
в качестве ключа к кешу dict
, но это работает только в том случае, если значения в kwargs
являются хешируемыми. Кроме того, как указано в ответах ниже, frozenset
не является упорядоченной структурой данных. Поэтому это решение может быть более безопасным:
(args, tuple(sorted(kwargs.items())))
Но он все еще не может справиться с не-хэшируемыми элементами. Другой подход, который я видел, - использовать string
представление kwargs
в кеше:
(args, str(sorted(kwargs.items())))
Единственный недостаток, который я вижу с этим, - накладные расходы на хэширование потенциально очень длинной строки. Насколько я вижу, результаты должны быть правильными. Может ли кто-нибудь выявить какие-либо проблемы с последним подходом? Один из приведенных ниже ответов указывает, что это предполагает определенное поведение функций __str__
или __repr__
для значений аргументов ключевого слова. Это похоже на шоу-стоппер.
Есть ли еще один, более простой способ достижения memoization, который может справиться с **kwargs
и значениями un-hashable?