Как использовать результат выражения из условия в ветке самого условия?

Вопрос по архитектуре кода. Допустим, есть множество elif'ов. В "верхних" условиях результат выражения не используется внутри ветки. Среди нижних есть условие, где результат выражения из if'а используется внутри ветки.


Вопрос:

Как написать код так, чтобы этот результат не высчитывался дважды (при проверке и внутри ветки) и не высчитывался лишний раз (если, например, первое условие пройдёт)?


Примерный код:

def task(val):
    if val % 2:
        print("cond1")  # результат выражения не используется
    elif val % 3:
        print("cond2")
    elif val % 5:
        print(val % 5)  # Тут результат из if'а используется внутри ветки
                        # и высчитывается второй раз. Этого хотелось бы избежать
    else:
        print("else")


task(6)


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


Ответы (2 шт):

Автор решения: Михаил Муругов

Спасибо @Xander за подсказку с кешированием. Реализовал класс-хранилище:

class Cache:
    def __init__(self, value=None):
        self.cached = value

    def __call__(self, func, *args, **kwargs):  # Вызывает func(*args, **kwargs) с 
                                                # кешированием результата
        self.cached = func(*args, **kwargs)
        return self.cached


cache = Cache()


def task(val):
    if val % 2:
        print("cond1")  # результат выражения не используется
    elif val % 3:
        print("cond2")
    elif cache(lambda x: x % 5, val):
        print(cache.cached)  # Используется кешированный результат функциии
    else:
        print("else")


task(6)

Выглядит очень костыльно, буду рад лучшим решениям.

→ Ссылка
Автор решения: MaxU

Воспользуйтесь стандартной functools.lru_cache() для кеширования результатов вызова функции:

from functools import lru_cache

@lru_cache(maxsize=2**14)
def my_long_running_func(arg1):
    return arg1 % 5

def task(val):
    if val % 2:
        print("cond1")  # результат выражения не используется
    elif val % 3:
        print("cond2")
    elif my_long_running_func(val):
        print(my_long_running_func(val))  # Используется кешированный результат функциии
    else:
        print("else")
→ Ссылка