For more information about topics covered in this lesson, you can check out these resources:
Enforcing Type Checking
00:00 Just because Python doesn’t use your attributes to do any type of type checking doesn’t mean that you, as a programmer, can’t do it on your own. Let’s take a look at how that might be done.
Here is a function, which is designed to check if the parameter values provided match the type that’s expected based on the annotation. It takes three parameters, and we would like that
a is an integer,
b be a string, and
c be a decimal value. To look at those values and their types, we’re going to import the
inspect library. That allows you to write code to inspect objects that exist while your program is being executed.
And in this particular case, we would like to get information about the arguments and their values when this function is called. The variable
args is going to store the arguments that are passed to this function,
annotations is going to store a collection of all of the annotations associated with this function. And we’re going to iterate through our collection of arguments.
So, the first time through this
x is going to represent the first parameter and its argument value, the second time through, it’s going to represent
b and the third time through, it’s going to represent
We’re going to have an output statement for each parameter. We’re going to list its value, we are then going to look up in the symbol table each value.
locals() returns the symbol table as a dictionary.
The symbol table simply is a list of all of the variable names that exist and their associated values, and so we’re going to find the type of each argument—the first time through,
'a', the second time through
'b', the third time through,
We’re going to see what type the argument actually is, then we’re going to look up in
annotations what the annotation wants it to be, and then we’ll apply a conditional. We’re going to check to see “Is the type of the argument the type that the annotation is expecting?” The first thing we will see for each argument is its type, the second thing we will see is what the annotation wants its type to be, and the third thing will be either the word
False depending on whether the argument type matches what the annotation says it should be.
So, when I call
f(), the function header appears showing me the annotations that
a is expecting an integer,
b is expecting a string, and
c is expecting a float.
We iterate through the list of arguments.
a was an integer. It’s supposed to be an integer, and so we get
True. The argument type matched the annotation.
b is a string.
It’s supposed to be a string, and so those types line up. The output is
c was given a floating-point decimal value. The annotation wanted it to be a floating-point value, and so that returns
True as well.
If I provide values that aren’t what’s expected, then for each one that is not correct, the last part of the output is going to be the word
False. In this case, all three of them are wrong.
a was a string. An integer was expected, and so those types don’t match. We output the word
b was a float. It’s expected to be a string. And
c was an integer, but it was supposed to be a float.
04:08 And you can have some correct and others incorrect.
So here, we can see that
b were of the types expected, but that
c wasn’t. Now, this could be important if your particular function depends on the values being the appropriate types.
04:30 And so what you could do is take some steps to prevent the function from continuing if one of the types was not correct, perhaps best throwing an exception or otherwise not running any more of the function, because the parameter types not being correct will cause other issues in the function later.
04:53 PEP 484 describes a scheme for doing some static type checking in Python, and there is a type checker called Mypy, which is built on that. So even though Python doesn’t enforce any type checking using attributes, there are certainly ways to make that happen.
Become a Member to join the conversation.