Как компактно написать проверку диапазона значений в функции?

Имеется функция для вычисления относительной длины форсунки, значение которое может принять эта функция должно быть в диапазоне от 1,5 до 6,0. При этом, если функция выходит за диапазон, то мы должны остановить дальнейшие расчеты и вывести ошибку.

@property
    def relative_length_tangential_hole(self) -> float:
        meaning = self.length_input_tangential_holes / self.diameter_input_tangential_holes
        if 1.5 <= meaning <= 6:
            return meaning
        else:
            return "Ошибка"

Я реализовал эту проверку так, но есть ли способ сделать это более компактно и понятнее? А также в случаи исключения об ошибке, следующие функции все равно будут запускаться и выдавать уже ошибку о некорректном значение этой. Как это исправить?


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

Автор решения: Amgarak

Можно посмотреть в сторону декораторов, и убрать проверку туда, дополнительно вывести своё исключение в случае bad диапазона.

def check_range(min_value, max_value):
    def decorator(func):
        def wrapper(self):
            meaning = func(self)
            if min_value <= meaning <= max_value:
                return meaning
            else:
                raise ValueError(f"Ошибка: значение {meaning} выходит за допустимый диапазон ({min_value} - {max_value}).")
        return wrapper
    return decorator

class MyClass:
    def __init__(self, length_input_tangential_holes, diameter_input_tangential_holes):
        self.length_input_tangential_holes = length_input_tangential_holes
        self.diameter_input_tangential_holes = diameter_input_tangential_holes

    @property
    @check_range(1.5, 6.0)
    def relative_length_tangential_hole(self):
        return self.length_input_tangential_holes / self.diameter_input_tangential_holes


try:
    myClass = MyClass(1, 2)  
    relative_length = myClass.relative_length_tangential_hole
    print("Относительная длина форсунки:", relative_length)
    print("Этот принт не отработает в случае ошибки")
except ValueError as e:
    print(e)

Ошибка: значение выходит за допустимый диапазон (1.5 - 6.0).

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

Более универсальное решение в дополнение к первому ответу:

def check_range(start, end):
    def check(func):
        def wrapper(*args):
            meaning = func(*args)
            if start <= meaning <= end:
                return meaning
            else:
                raise ValueError("Ошибка: значение выходит за допустимый диапазон (1.5 - 6.0).")
        return wrapper
    return check


@check_range(1.5, 6.0)
def relative_length_tangential_hole(length_input_tangential_holes, diameter_input_tangential_holes):
    return length_input_tangential_holes / diameter_input_tangential_holes


try:
    relative_length = relative_length_tangential_hole(10, 5)
    print("Относительная длина форсунки:", relative_length)
except ValueError as e:
    print(e)
→ Ссылка
Автор решения: Алексей Р

По-моему, у вас все вполне понятно и компактно. Чтобы поток исполнения не шел дальше, просто замените

else: 
    return "Ошибка"

на

raise ValueError('Ошибка ...')
→ Ссылка