enforce arguments to a specific list of values
Question:
What is the pythonic way to enforce a function to take a specific set of values for a given parameter? For instance there is a function like:
def results(status, data):
I want to restrict the parameter status
to a set of values like 0, 1 or 99.
Answers:
You can check within the function itself if status
is a valid value and if it is not then raise an exception.
def results(status,data):
list_valid_status = [0, 1, 99]
# list_valid_status = (0, 1, 99) # could be a tuple so it doesn't get modified by accident
if status not in list_valid_status:
raise ValueError("Wrong status")
You need to check the value inside the function:
def results(status, data):
valid = {0, 1, 99}
if status not in valid:
raise ValueError("results: status must be one of %r." % valid)
Here, valid
is a set, because the only thing we care about is whether status
is a member of the collection (we aren’t interested in order, for example). To avoid recreating the set each time you use the function, you’d probably define it as a “constant”1 global:
VALID_STATUS = {0, 1, 99}
def results(status, data):
if status not in VALID_STATUS:
raise ValueError("results: status must be one of %r." % VALID_STATUS)
Example usage:
>>> results(7, [...])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in results
ValueError: results: status must be one of {0, 1, 99}.
Always try to raise the most appropriate exception you can – ValueError
tells the caller of the function what’s going on better than Exception
does, for example.
1 It’s not really constant, but by convention, ALL_UPPERCASE
variable names in Python are considered to be intended as constants.
An alternative option would be to go with Enums for instance
from enum import IntEnum
class STATUSES(IntEnum):
ZERO = 0
ONE = 1
OTHER = 99
def results(status, data):
status = STATUS(status)
calling STATUS(status)
would raise ValueError
similar to other answers, but with this approach you have some benefits:
- Putting type annotation
status:STATUSES
would make it easier for others to get set of valid fields (especially when working with IDE)
- You can name
STATUSES
in human-readable format (don’t have a broader context of this particular use case)
What is the pythonic way to enforce a function to take a specific set of values for a given parameter? For instance there is a function like:
def results(status, data):
I want to restrict the parameter status
to a set of values like 0, 1 or 99.
You can check within the function itself if status
is a valid value and if it is not then raise an exception.
def results(status,data):
list_valid_status = [0, 1, 99]
# list_valid_status = (0, 1, 99) # could be a tuple so it doesn't get modified by accident
if status not in list_valid_status:
raise ValueError("Wrong status")
You need to check the value inside the function:
def results(status, data):
valid = {0, 1, 99}
if status not in valid:
raise ValueError("results: status must be one of %r." % valid)
Here, valid
is a set, because the only thing we care about is whether status
is a member of the collection (we aren’t interested in order, for example). To avoid recreating the set each time you use the function, you’d probably define it as a “constant”1 global:
VALID_STATUS = {0, 1, 99}
def results(status, data):
if status not in VALID_STATUS:
raise ValueError("results: status must be one of %r." % VALID_STATUS)
Example usage:
>>> results(7, [...])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in results
ValueError: results: status must be one of {0, 1, 99}.
Always try to raise the most appropriate exception you can – ValueError
tells the caller of the function what’s going on better than Exception
does, for example.
1 It’s not really constant, but by convention, ALL_UPPERCASE
variable names in Python are considered to be intended as constants.
An alternative option would be to go with Enums for instance
from enum import IntEnum
class STATUSES(IntEnum):
ZERO = 0
ONE = 1
OTHER = 99
def results(status, data):
status = STATUS(status)
calling STATUS(status)
would raise ValueError
similar to other answers, but with this approach you have some benefits:
- Putting type annotation
status:STATUSES
would make it easier for others to get set of valid fields (especially when working with IDE) - You can name
STATUSES
in human-readable format (don’t have a broader context of this particular use case)