Checking Argument Types
00:00
Checking Argument Types in .__init__()
. Another approach to simulate multiple constructors is to write a .__init__()
method that behaves differently depending on the argument type. To check the type of a variable in Python, you commonly rely on the built-in isinstance()
function.
00:20
This function returns True
if an object is an instance of a given class and False
otherwise. The first argument isinstance()
is the object that you want to type check.
00:30
The second argument is the class or data type of reference. You can check if the number 42
is an integer or a float.
00:42
You can also pass a tuple of types to this argument, allowing checking against the classes in the tuple and returning True
if any of them match. If you’re running Python 3.10 or later, then you can also use the new union syntax with the pipe symbol (|
).
01:01
Now, let’s say that you want to continue working on your Person
class, and that you need that class to also accept the person’s birth date.
01:08
Your code will represent the birth date as a date
object, but for convenience your users will have the option of providing the birth date as a string with a given format. In this case, you can approach it in the way seen on-screen.
01:30
Inside .__init__()
, you first define the usual .name
attribute. The if
clause of the conditional statement checks if the provided birth date is a date
object.
01:40
If so, then you define .birth_date
to store the date at hand. The elif
clause checks if the birth_date
argument is a string. If so, then you set .birth_date
to a date
object built from that provided string.
01:56
Note that the birth_date
argument should be a string with the date in ISO format year-month-date. And that’s it! You now have a .__init__()
method that simulates a class with multiple constructors.
02:11
One constructor takes arguments of date
type, and the other constructor takes arguments of string type. What would happen if your user input a Unix time value for birth_date
?
02:23 You can see what would happen on-screen.
02:30
When you access .birth_date
, you get an AttributeError
because your conditional statement doesn’t have a branch that considers a different date format.
02:41
To fix this issue, you can continue adding elif
clauses to cover all the possible date formats that the user can pass. You can also add an else
clause to catch unsupported date formats.
03:16
In this example, the else
clause runs if the value of birth_date
isn’t a date
object or a string holding a valid ISO date. This way, the exceptional situation doesn’t pass silently.
03:31 But as you can probably see, the technique seen here has the drawback that it doesn’t scale well. If you have multiple arguments that can take values of different data types, then your implementation can soon become a nightmare.
03:44 So this technique is considered an anti-pattern in Python. PEP 443 therefore introduced single-dispatch generic functions to help you avoid using this coding anti-pattern whenever possible.
03:58 You’ll learn more about this feature later on, but in the next section the course, you’ll see how to use class methods as a Pythonic way to provide multiple constructors for your classes.
Become a Member to join the conversation.