Запретить вызов функции более одного раза, если параметры использовались ранее - PullRequest
0 голосов
/ 18 февраля 2020

Я бы хотел ограничить вызов функции одним разом для значений параметров.

Например,

def unique_func(x):
    return x

>>> unique_func([1])
[1]
>>> unique_func([1])
*** wont return anything ***
>>> unique_func([2])
[2]

Есть предложения? Я рассмотрел использование мемоизации, но пока не нашел решения.

Это не решается предлагаемым Предотвращение вызова функции два раза подряд , поскольку она решается только тогда, когда предыдущий забавный c вызов имел их параметры.

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020

Memoization использует отображение аргументов для возврата значений. Здесь вы просто хотите сопоставить аргументы с None, которые могут обрабатываться простым набором.

def idempotize(f):
    cache = set()
    def _(x):
        if x in cache:
            return
        cache.add(x)
        return f(x)
    return _


@idempotize
def unique_fun(x):
    ...

С некоторой осторожностью это можно обобщить для обработки функций с несколькими аргументами, если только они пригодны для использования.

def idempotize(f):
    cache = set()
    def _(*args, **kwargs):
        k = (args, frozenset(kwargs.items()))
        if k in cache:
            return
        return f(*args, **kwargs)
    return _
0 голосов
/ 18 февраля 2020

Подумайте об использовании встроенного functools.lru_cache() вместо собственного.

Он не вернет ничего при втором вызове функции с теми же параметрами (он вернет то же самое, что и первый вызов функции), но, возможно, вы можете жить с этим. Казалось бы, это незначительная цена, которую нужно заплатить, по сравнению с преимуществами использования чего-то, что поддерживается в стандартной библиотеке.

Требуется, чтобы ваш аргумент x был хэшируемым, поэтому не будет работать со списками. Строки в порядке.

from functools import lru_cache

@lru_cache()
def unique_fun(x):
    ...
...