This will be a example-driven presentation. The first set of examples looks at
an int
which should be restricted to a value from one through ten.
First I'll look at the problems in the traditional approach, passing an int
to a function and checking to ensure it is within range.
Next I'll encapsulate the int
in a (regular) class OneToTen
, which allows
the movement of the test into the constructor. Although this guarantees that
objects will be created correctly, such objects are mutable so they can be
modified to be invalid after creation.
The solution is to use @dataclass
together with the frozen=True
option, and
add a __post_init__
function to check the validity of the object once it's
been initialized. Because such an object is invariant, it cannot be later
modified into an invalid state. This ensures that the new type can only ever
exist as a legitimate value.
Next I'll use this technique to create a Person
type that is composed of
FullName
, BirthDate
and EmailAddress
fields, each of which validates
itself. Finally, I'll compose BirthDate
using Day
, Month
and Year
fields.