Some data value use a basic type like str
or int
, but not all str and int are valid values of that data value. Enums can limit the possibilities to only a defined set of values.
Example:
Blood type is a string, but have a set of only 8 valid strings. Don’t exist a blood called 'randombloodtype'
but 'AB-'
is valid.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from enum import Enum
class BloodType(str, Enum):
A_negative = "A-"
B_negative = "B-"
AB_negative = "AB-"
O_negative = "O-"
A_positive = "A+"
B_positive = "B+"
AB_positive = "AB+"
O_positive = "O+"
assert "A-" in list(BloodType)
assert "O+" == BloodType.O_positive
So why not just use list?
The below code do the same as the above:
1
2
3
4
5
6
7
8
9
10
11
12
BLOOD_TYPE = [
"A-",
"B-",
"AB-",
"O-",
"A+",
"B+",
"AB+",
"O+",
]
assert "A-" in BLOOD_TYPE
But let us suppose we should make a new piece of code. Given the donor blood type, returns the list of allowed recipients.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
from typing import List
def blood_type_can_donate_to(donor: str) -> List[str]:
_recipients = {
"A-": ["A-", "AB-", "A+", "AB+"],
"B-": ["B-", "AB-", "B+", "AB+"],
"AB-": ["AB-", "AB+"],
"O-": ["A-","B-", "AB-", "O-", "A+", "B+", "AB+", "0+"],
"A+": ["A+", "AB+"],
"B+": ["B+", "AB+"],
"AB+": ["AB+"],
"O+": ["A+", "B+", "AB+", "O+"]
}
return _recipients[donor]
And using enum:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
from enum import Enum
from typing import List
class BloodType(str, Enum):
A_negative = "A-"
B_negative = "B-"
AB_negative = "AB-"
O_negative = "O-"
A_positive = "A+"
B_positive = "B+"
AB_positive = "AB+"
O_positive = "O+"
def blood_type_can_donate_to(donor: BloodType) -> List[BloodType]:
if donor == BloodType.A_negative:
return [
BloodType.A_negative,
BloodType.AB_negative,
BloodType.A_positive,
BloodType.AB_positive
]
elif donor == BloodType.B_negative:
return [
BloodType.B_negative,
BloodType.AB_negative,
BloodType.B_positive,
BloodType.AB_positive
]
elif donor == BloodType.AB_negative:
return [
BloodType.AB_negative,
BloodType.AB_positive
]
elif donor == BloodType.O_negative:
return list(BloodType)
elif donor == BloodType.A_positive:
return [
BloodType.A_positive,
BloodType.AB_positive
]
elif donor == BloodType.B_positive:
return [
BloodType.B_positive,
BloodType.AB_positive
]
elif donor == BloodType.AB_positive:
return [
BloodType.AB_positive
]
elif donor == BloodType.O_positive:
return [
BloodType.A_positive,
BloodType.B_positive,
BloodType.AB_positive,
BloodType.O_positive
]
The second one does exactly the same as the first one, but have some big advantages:
- Help you to avoiding mistakes.
- Help to code editor to warning if you make a mistake.
- Help to the next person to works in the code, avoid mistakes.
See the first version again: It has a typo error, a 0 instead of a O.