How to limit an input parameter's value range in a python way?

483 views Asked by At

If I design a function like

def f(a, b):
  ...

a must be in [1,2,3]. If I pass 4 to parameter a, it should raise an exception. Is there a pythonic way to limit the value range of a function argument?


Added Please note, is there a more pythonic way to implement it? Not just a simple assert or if in. For instance, decorator or maybe some syntactic sugar.

2

There are 2 answers

2
Freeman On BEST ANSWER

Yes, and also you can raise an exception if the input value is outside the desired range. For example, let's say you have a function called f that takes two integer parameters, a and b. To limit the range of a, you can use an annotation like a: int to specify that a should be an integer. Then, you can add an if statement to check if a is within the desired range. If it's not, a ValueError will be raised with a specific error message. So, if you call the function with an invalid value for a, like 4, it will raise an exception.

def f(a: int, b: int) -> int:
    if a not in [1, 2, 3]:
        raise ValueError("Invalid value for 'a'. Expected 1, 2, or 3.")
    
    #rest of your functions
    
    return result

update

In this new example, I created a decorator called value_range that you can use to limit the range of a function argument, and it's super easy to use, just apply the decorator to your function f and specify the range values you want, as you see if you pass a value outside that range, it'll raise a ValueError. It's a really neat and pythonic way to keep things in check without messy assert or if statements!

from typing import Union

def value_range(min_value: int, max_value: int):
    def decorator(func):
        def wrapper(a: Union[int, float], b):
            if not min_value <= a <= max_value:
                raise ValueError(f"Invalid value for 'a'. It should be between {min_value} and {max_value}.")
            return func(a, b)
        return wrapper
    return decorator

@value_range(1, 3)
def f(a: int, b):
    #rest of your functions
    pass
3
jlgarcia On

Numerous ways to do this, but I really like the assert clause:

def f(a, b):
    assert a in range(3), "Exception message raised because parameter 'a' is not in [0, 1, 2]"
    # Your code

When a is not in your defined valid range, the function will raise an AssertionError, displaying your message.