Python Institute PCAP – Modules, Packages and Object Oriented Programming in Python Part 2
- Classes Attributes vs Object Attributes
Constructor, right, which is supposed to construct the object. And what are the two values that are needed to construct an object properly? We have a body type and then the make, okay? And this could be a very long list of values that are needed to construct depending on how you define a vehicle. So we want to keep things simple. And we only have two values here. This self, it’s just an automatic thing. We need to have the self be the first argument of a given method in a class. And this represents this represents the instance itself. So the instance of this vehicle, class, that’s what self represents. Now, what is an instance? Car one is an instance. Car two is an instance. Car three is an instance, and so on. That self basically represents each of these instances or objects, okay? So these variables are associated with the instance. These are instance variables. There’s also another kind of variable that I want to talk about now, and that is known as the class variable or class attribute. Think of these as instance attributes or instance variables.
A class attribute or class variable is something that is independent of a given instance. Okay? So if we were to define, for example, a color variable up here and say that color is red just like that. Now, all of our vehicles, car one, car two, car three, up to car six, all of these, as well as any other vehicle that I create, is automatically going to have the color red, okay? Because that’s part of the class. This is a class definition that we’re defining. We’re making changes to the template of what a vehicle is. And so we’re saying that every vehicle that gets created by this class is going to have the color red. And so I’ll prove it to you. If you were to print, for example, let me change this print statement and say, car one, dot color notice. Now, we can actually refer to the variable because this is a class variable or a class attribute. It’s not inside of any method. And typically, all your class variables or class attributes should be outside of any methods up all the way to the top, right underneath the class definition.
And this is supposed to be something that should not be changed, okay? This should not be changed. Even though Python is very flexible, it does allow you to the ability to change this while, you know, later in your program, even though it’s defined as something else in a class. You can, and I’ll show you how to do that change the value of color later on in your program. And that’s actually a very bad practice. And we’ll go over that in just a moment. But let’s let’s print the color of all these vehicles. All right? So car one, car three, let’s check car six. And now let’s print this, and you’ll see that all of them are in fact, red. If I change this class variable to green, then of course it will be green. Let me put this comment right above the class attribute here. Similarly, if I had another variable, a class attribute variable such as engine, and we say that it’s V Six, then all of our cars will, of course, have the V Six engine. Now, let me show you where things can get ugly in Python. If you, for example, have a class variable like this, it’s usually something that’s meant to be static. It should not be changed. It’s associated with the definition of what a vehicle ought to be like, right? And so all of our vehicles, we might as well rename this class red vehicle, because that’s all this vehicle is capable of generating. But someone, let’s say, a beginner coder, can go ahead and change this. The way a user can go ahead and change this is outside of the class, outside of this class definition.
Now, I’m onto bigger and better code. The class ends here. After this line, I can actually change a class attribute. And the way to do that is we use the vehicle class with the capital V. Make sure you spell it correctly. You do vehicle dot, and then you do color and change it to, for example, green. And now all of these cars, after this line is run, all of these cars are going to have the color green. And so, when we run this, notice car one, car two, three, and six. All of them basically have the color green because this line has been executed. Now, you might think that that’s okay, right? In this small 2030 line code, it doesn’t really matter. But imagine if you have a fairly large program and you have thousands of lines of code, and someone sees your class and says, okay, there’s a constant that should not change. It’s a color. It’s part of what a vehicle is in our situation.
And so this class is basically only capable of generating red vehicles. Great. But let’s say somewhere down, like on the thousandth line, there’s this line right here that changes the color. And you’re trying to create a vehicle, and you expect to use this vehicle class to be able to create red cars. And all of a sudden, you see that all your cars that you’re creating are green or blue or some other color. Then you have to go in the code in all those lines, thousands of lines, and search to see where is this class attribute being changed? Some beginner coder may have entered this line. So, as you can see, this could be a design problem. So the idea behind introducing a class attribute like this is it should never be changed, okay? Even though Python allows the flexibility to be able to do that outside of your class, you should never do that. Python is a very flexible language, and it allows you to do many things, but that doesn’t mean you should be doing them.
It leaves room for many more errors. And so the standard practice, you want to, you want to follow best practices. And I’ll be discussing best practices as we go along. This is one of them. Now, another thing that people often do is they can assign willy nilly any object, any attribute they want with a value. I’ll show you an example for car one. If I change car one and say dot color is equal to purple, what am I doing here? I’m not changing the vehicle specifications color to be green. I’m actually changing this object to have a property named color, which is going to be purple. See the difference? I’ll prove it to you. So vehicle specification, this class, again, it’s a specification of blueprint on which all these other vehicles are being created, these cars.
And so we changed the vehicle specification color to be green at this point. And so now all these cars are going to have green except for car one is going to have the color purple. Okay? And so we can print the color for each of these cars and you’ll see, let’s run it. Notice car one is purple, but the rest of the cars are still green because the specification is still green for them. And so car one, it’s utilizing a vehicle that has a specification with the color green. But now what we have done is assigned this particular car object an instance variable called color and it’s purple. So now we have introduced an instance variable for car one that is color. This is different than changing the class specification color variable to be red, right? The class attribute to be red or green here. So what a lot of people do sometimes, and that causes things to get messy in Python, is they take an object, let’s say car one, and they assign other instance attributes to it, right? Let’s say engine, and we say engine is going to be V six. Now, the funny thing is, the vehicle class on which this car is supposed to be based on, this car one is supposed to be based on, does not have the engine as an instance attribute.
You can see in the constructor of how a car should be built, it doesn’t have the engine. But we are now assigning a new instance variable to the car one object and we’re giving it the value V six. And so now car one has the engine attribute, but the rest of the cars do not have an engine attribute. So let’s do that. Let’s print the engine value for car one. And if I tried to do that for car three as well as car six, notice the, the Python interpreter is complaining right here. Unresolved attribute reference engine or class vehicle for class vehicle.
So these objects do not have an engine, whereas this one does. Now, these are all based on the specification of what a vehicle ought to be, which is right here. So could you notice where there are issues with this design or how this design could be abused, where a programmer is utilizing this class to create vehicles, but then they’re willy nilly assigning the instances their own attributes. You should never do this. Okay, if you’re going to work with object orientation and you’re going to work with a class like this, follow this class specification.
All Right? You can always change the specification by changing the color to be something or introducing an engine in the constructor or as a class attribute. But don’t, willy nilly, go ahead and change your objects and give them random values like this because it makes interpreting your code much more complicated for someone that hasn’t. And you might come to your code after a month and completely forget that, hey, I did this to this object. Whereas the rest of the objects are following this particular specification. But car one is not, even though it’s based off of the specification of vehicle.
So there’s a lot of flexibility in the Python language. And this flexibility could cause some programmers to go astray. And you should definitely not do that. That’s just you’re going to run into all kinds of design smells in your programs. So there’s another best practice that I’m recommending. Follow a class specification. If you’re going to create an object based on a particular class definition, have that object only comply with that class specification. Don’t change that object to have more things than what the class allows. Now, other languages such as Java and C plus plus C sharp, those are far more strict. And they treat a class as a very serious contract. If you’re going to utilize a class to create an instance or create an object from a class, it’s not going to let you willingly assign these attributes if those are not defined in the class’s specification.
But you can see that in Python we have that flexibility. So with power comes a lot of responsibility. So if you want to write good code, follow the recommendations that I’m giving you. I took a moment, I paused the video and I added some comments. And this file will be part of this lecture. So make sure you download it and play around with it. So what did I write here? I said the color should not be changed outside of the class specification. And this is the class specification. This is a class attribute. So now, why would you use a class attribute? What are some of the reasons? Well, for example, let’s say you have a constant that is not supposed to change in your program. Let’s say you have a circle class. Well, the Pi number, which is 3. 14, is used a lot with circle calculations. Let’s say you want to calculate the circumference or the diameter and so on the area of a circle.
In all those calculations, the pi number is used and that’s a constant number. 3. 14. So in a situation like that, you can have a class variable. So any instance of a circle would, of course, comply with the number of pi being 3. 14. That’s a constant in your program. Or let’s say you’re writing a physics engine or game where the speed at which gravity pulls an object down, I don’t even know what that is, but let’s say it’s nine point something miles per second or something. It might be much more than that. But anyway, that gravity. That calculation for gravity is probably a constant that should not change. And so in those instances, you have a class variable. So anything that has to do with, for example, the gravity or any other object that has to do with gravity, it’s going to utilize that constant, that class variable. In this case, of course, color is not a big deal. Let’s change this to something that is more reasonable. Let’s say that we want to count the number of vehicles in our program. What we can do is we can create a vehicle count number, vehicle count variable.
And this is a class variable, and we’ll say that it initialized with zero. So every instance of vehicle that’s created is going to have a vehicle count of zero. So what does this mean? Well, let’s say that we want to track how many vehicles have been created in our program or constructed in our program. Now, in this situation so far, we’ve got by the way, I’ve added various comments to this. So that’s why you’re seeing this when I pause the video, and I recommend you look at this file and go through this. But if you scroll down, we’ve got up to six vehicles. Okay? So we created six instances of the vehicle class. So now what we can do is we can use this vehicle counter. Let me change this to counter. With an er counter. We can modify this vehicle counter number every time a vehicle has been created. But again, what’s the rule? This is a class attribute. It should not be changed.
Let me change this to this variable. This variable should not be changed outside of the class specification. So we could change it inside, right? So let’s say every time a vehicle is created, this method will always run. That’s a given. This method will always run. It’s a constructor method in it means to initialize objects of the vehicle class. So anytime we create a new vehicle, such as we’re doing down here, this method is going to run. So as part of the body of this method, I can actually do vehicle counter and do plus equals one. Now, it’s not going to work just like this. We need to associate this with the class. We’re not associating it with the with a given object. So we cannot do self dot, because then that means car one or car two will have separate values for vehicle counter. So this needs to be associated with this class definition. This is a class variable. So the way we can modify this as new objects get created, we do vehicle dot, vehicle counter.
So this is the vehicle class. Make sure you spell it correctly with the capital V and then the vehicle counter. Now we’re modifying every time this constructor method is run, the vehicle counter is incremented. Okay? And so now we can also have, for example, another method. As part of this class definition, we can have another method called we can call it get vehicle count. And this is just going to return the vehicle count. We could just do return the vehicle counter like that. And again, we can’t refer to the vehicle counter just like that. We need to either associate with an instance using the self or the class. Now, again, this is a class variable. This will be independent of any instances that get created from this class specification. So we need to make sure we do vehicle vehicle counter, okay? If I do self vehicle counter, it’s not going to complain because it doesn’t know what we’re trying to do.
But guess what? We’re only going to get the counter for a given vehicle, whether it’s car one, car two, car three, and that’s no good. Let me prove to you what happens if we do this. If I print the value for this get vehicle count for each of these vehicles. Car one, car two, car. You’ll see how the values are changing? So let’s do this. Car one, get vehicle count. So we need to use the print statement because this method just returns this just returns the value. It doesn’t print it. So we’re putting it inside of print line statement. And I’m going to do that for a couple of different vehicles. Vehicle one, let’s do for car two and then for car three as well. Like that. All right, everything else is commented out. So we should just see these three. So let’s run this and you’ll see what happens. Six. Six. Six. Why is that? Well, the vehicle counter, every time car one, car two, car three kept being constructed, the vehicle counter was incremented because of this line. And so after six cars were constructed, the vehicle count here is going to show the same for all three cars or all six cars. And so you might say that that’s okay. But remember, this is not correct. The correct way to reference is we’re not associating with an instance. We’re associating it with the class.
So we have to do vehicle vehicle counter. Okay? And this code will then run pretty much exactly the same, but it’s designed much better. Okay? Now if we were to get the vehicle count on after this line, after car two, there will be two cars. It’ll show that the number is two. If we do it after three, then it will show that the number is three and so on. Hopefully you get the idea. So that’s it for now. I want to leave you with this.
Make sure to go through this file, check out the notes that I left and review it, play around with it, change it around, and see what happens. Now, one thing I’d like to point out is that every method that you create that is going to be part of a class, such as this vehicle class or any other class, the first argument that it expects is the self. And this is supposed to represent the instance that will be created based on this specification, based on the class specification. All right, so let’s just go ahead and you’ll see the editor populates our method with the self by default. So if we do def, let’s say that we want to display make. Let’s say we want to display the make of the vehicle. Now, if I do open closed parentheses automatically, notice it gives a self.
Because if we want to display the make, we’re going to display the make of a given car, whether it’s car one, car two, car three, car four, each of those objects. And that’s what self is. It represents the instance that this method is going to be invoked on. Okay, now, you can, of course, add other methods to this excuse me, other arguments to this, such as comment or something, and it’ll display the make with the comment that you write or some number that you pass into this. Of course, you can add all those arguments, arguments to this, but you must also have a self before all the other arguments.
- Calling Python Code That is Saved in Another File
Here’s a class that we create. In the previous lesson, I got rid of all the other stuff that was underneath there, and I just left the barebone class with the constructor method and the get vehicle count method. And that’s it. Now what I can do is I could put away this code in some file and save that file somewhere. And so let’s do that. I’ll show you how we can call that file. Use this class to build objects in another file. All right, so we’ll go over that. It’ll make sense when I create the example. So let’s create a new folder in the Hello World Project. Right click and go to New and click on folder. And I’m going to call this folder Machines, because this will store machines.
And I think a vehicle is a kind of machine, right? So now inside of this folder, I’m going to right click and go to New. Choose Python file, and I’m going to name the Python file vehicle underscore Stuff. Okay? And I did this on purpose to prove a point that your file name does not have to be the same as the class name. Some languages such as Java and C plus plus require you to have your file be the same name as the class name. So that’s not a requirement in Python. So let’s copy this, or rather cut this code out and paste it into the Vehicle Stuff file. And let’s save this file and close it. Okay. And so now we’ve got this Machines folder. In this machines folder. We got the vehicle stuff. That PY, which contains our vehicle class. Now this file is going to have other classes which we’ll get into later, but how would you use the vehicle class?
Now, in my application, PY, we don’t have accessibility directly to the machines unless we write it in a certain way. And I’ll show you how to do that. So let’s first try to create a new object. Let’s car one is equal to vehicle. Notice it’s going to complain unresolved reference vehicle. It doesn’t know what it is. So to be able to utilize the vehicle code that we’ve written to form this object, here’s what you need to do. You need to do from there’s a new keyword that I’m introducing. And then you specify the folder name in which that code resides. So that’s machines.
And then the file name, which is Vehicle Stuff. And then you import the particular class. Now, in that file, we only have one class right now. Again, later, we’re going to be putting multiple classes in that file. But let’s just import the one and only class we have for now, and that’s the vehicle class. So as soon as you import that, notice the error goes away. And now we can create the car and create multiple car objects using the vehicle specification. All right. So now let’s actually I’ll leave this code the way it is in Application PY. I’m going to go into the Machines folder and in the Vehicle Stuff PY class, and I’m going to start adding more classes to this that has to do with vehicles. Obviously, we don’t want to write a class in this file that has nothing to do with vehicles because then why did we name it Vehicles Stuff? So you want to kind of organize your code, and we’re going to be working on designing our projects as such so that they’re well organized and that’s all part of object orient.
- Inheritance and Polymorphism
So a fundamental concept in objectoriented programming that I’m about to introduce to you right now is inheritance. And it is exactly what it sounds like. If you’ve already written code that does certain things and you want to reuse that code, you can inherit that functionality in another class as long as it makes sense to do so. So, for example, we have this vehicle class, right? And I know the examples right now are abstract. It’s not like we’re creating a Tesla factory. Where are our vehicles? I don’t see any vehicles, do you? Why do we even have a vehicle in this program? Don’t worry, we’re going to get more practical with this. Right now, I just want to keep it abstract to explain to you the examples of how object orientation works. Okay? So we’re going to get more specific. So let’s stick with this vehicle example for now to understand the concepts, and then we’ll graduate to better things. So if we wanted to inherit some of the functionality of a vehicle, we could do it in a Subclass. What’s a Subclass, you might ask? Well, a class that is a kind of vehicle. So this is a sort of a generic term, right? A vehicle could be anything. Like a truck is a vehicle, a car is a vehicle.
A motorcycle is a vehicle. A boat is maybe considered a vehicle, a plane even. So, let’s actually create a specific kind of vehicle. So outside of this vehicle class, I’m going to create another class called truck. Okay? And this truck is a kind of vehicle. And the way we can specify that this class should inherit the functionality of the vehicle is we specify in these parentheses, vehicle like that. And then for now, I’m just going to add pass. We’ll fill this class out momentarily. But I want to tell you that now we can utilize the same code in the vehicle class, in the truck class. Okay? So let’s go over that example. So I got rid of the previous code here. I’m going to import the vehicle. And so if I was to create a truck, I could do truck. One is equal to new. Excuse me, not new. But we just need the truck keyboard. That’s it. So this is how you create a truck. Now hover your mouse here. It says unresolved reference. It doesn’t know what truck is. So we have to of course, import the truck from the proper file. And that’s in the vehicle stuff file, which is right here.
So we want to make sure we include that in the import. So we do truck right here. There we go. And so now it’s going to compile fine. So with this line, now we’re able to create a truck. Pretty cool, right? Now, I know it doesn’t do much, but trust me, you’re going to see all different types of examples where you’ll start to apply these concepts and really appreciate object oriented design. So we got truck one. Now let’s do truck two. I’m just going to create a couple of trucks and truck three. Now these are three truck objects, but keep in mind that these are also three kinds of vehicles. And so the functionality in the vehicle class, we’ve got this get vehicle count. Now, you can invoke believe it or not, you can invoke the get vehicle count on the truck because the truck class is inheriting from the vehicle all the functionality. So let’s try to get the vehicle count so we could do truck three, vehicle count or I think it’s called get vehicle count. Get vehicle count. And we are just going to print the value of invoking this method. And so let’s run this. Boom. There we go. We got an error.
And I did this on purpose. I want you to know why this error happened. Notice it says type error in it missing two required positional arguments body type and make. Why is this showing this? Well, the reason is because guess what? We’re trying to create a truck. And in the code, we’re specifying that this truck class, this truck object, is going to be a type of vehicle. Well, if it’s a type of vehicle, we better construct it like a vehicle is supposed to be constructed. And how is a vehicle supposed to be constructed? Let’s look at the constructor here in the init method. To create a vehicle properly, we need the body type and we need to make. And so we’re not doing that for any of our trucks here. So let’s give them some body and make.
So a truck body, I don’t know, we can say big rig, an 18 wheeler. And the make could be a Mercedes truck. And we can have a small rig. I don’t know the different types of truck bodies. And let’s say that this is a Chevy and I’m going to do the same thing. We’re going to have another big rig and this is going to be a Toyota truck. And so now if we run this, notice it says three because we created three vehicles, essentially because a truck is a vehicle based on this definition. Now, if I get rid of this now, we’re no longer going to inherit the vehicle functionality. Now this truck is on its own. So if we go here, notice we get some errors. Hover your mouse. And it’s saying that unexpected arguments. It doesn’t know what truck is with this argument. It also doesn’t know what vehicle count is. Hover your mouse. Unresolved reference get vehicle count for class truck.
Because this method does not exist in the truck class, it exists in the vehicle class. And this truck has nothing to do with the vehicle right now the way we have it coded. So to fix this, we of course need to inherit the functionality of a vehicle by putting vehicle class right here inside of these parentheses. And now this code is going to work fine. If we had another method, for example, for vehicle, we can have a method called drive or something and we can print that driving. All right? Now all of a sudden truck will have the ability to drive. So I can invoke truck, truck one, for example, to drive. And if we run this notice, it says driving. Now it’s driving based on the definition of the drive method defined in the vehicle class. And I can make this say vehicle driving. But for a truck to drive might be different. So I can redefine this drive method in the truck class like so, and make it more specific, make it more specific to a truck and say instead of vehicle driving, it’s a truck driving.
Okay? So now truck class is an herding vehicle. And truck class has one specific method called drive. Now this method is the same as this method in terms of how they’re named and their arguments. This is known as overriding. We are overriding the method that is defined in the vehicle class and we’re giving a more specific version to the child class, truck. Now, truck is a child class of vehicle. This is a terminology that you might hear or a subclass of vehicle. Vehicle is a parent class or a base class. Truck is a subclass or a child class of vehicle. And so now let’s go back to our application PY file this truck, one drive is no longer going to say driving or vehicle driving. It’s actually going to say truck driving. Let’s run this notice. It says truck driving because we have overwritten, or rather it’s known as method overriding. We overrid the method drive that was defined in the vehicle.
Now, similar to this, I can have another class. I’m just going to copy some of this code. And now we have the third class and let’s change this class to motorcycle. Now, motorcycle is also inheriting from the vehicle. It’s going to inherit all the methods or functionality of a vehicle and it also has its own drive method. And I could change this instead of truck driving, I could say motorcycle driving very fast or something. And so now if I was to of course create an instance of motorcycle and invoke the drive method, it’s going to print that the motorcycle is driving very fast. So all three of these classes have the method drive. And we are overriding the vehicle to drive method in these specific types of vehicles, the truck vehicle as well as the motorcycle vehicle. Both of these vehicles have their own versions of the drive method. And so when you invoke the drive method on a motorcycle, it’ll give this specific response.
If you invoke the drive method on a truck object, it’ll give this specific response and so on. Now this brings us to our next important concept in object oriented programming and that is known as polymorphism. And the polymorphism the term basically means the ability to take various forms. Okay, so what do I mean by that? Well, if we had, for example, A for loop, looping over a set of vehicles, let’s actually change some of this. So we have one truck. Let’s say that we have one car. We’ll say car one, and we’ll say motorcycle one. All right, so we got truck one, car one. And instead of motorcycle, I’ll just say moto one to keep it short. And these are going to of course the truck is going to initialize using the truck class. The car is going to initialize using the vehicle class. Let’s just say. And the motorcycle is going to initialize using the motorcycle class.
Now, of course, we don’t have motorcycle imported here, so we need to import that new class that we defined. And so now that will compile. And let’s change the arguments here to make it seem more sensible. So a car could be sedan, and let’s just leave it as a Chevy and a motorcycle. We could say the body type is two seater. Or let’s keep it simple and say sports. It’s a sports motorcycle. And we’ll say that this is a Honda motorcycle. And we’ll get rid of some of this code down here. And if we had a loop, for example, where we could say four item in and we have a list of objects. So truck one, car one and moto one. We can invoke the items or whatever vehicle. This should probably be titled vehicle. But I don’t want you to confuse this as the base class for these. So I’m just going to say it’s a Veh or just V for vehicle. And we can say V dot drive.
Now, if I run this for loop, if I run this code, it’s going to invoke the drive method, the same method. It’s going to invoke the same method, but it’s going to give different results because we have three different objects. So that’s the idea behind polymorphism. It means the ability to take various forms. So this particular code has the ability to take various forms. It runs the same method, drive. But the behavior is going to be different. So let’s run this and you’ll see truck driving, vehicle driving, motorcycle driving very fast. So you might be wondering, behavior, different behavior. How is this different behavior? They’re just pretty much doing the same thing. They’re printing to the screen, although they’re printing different things. Well, I want you to think of these as three totally different objects, okay? In this simple, silly example, we’re talking about trucks and vehicles and so on.
But in an actual program, let’s say that we had these objects responsible for conducting various operations with files and downloading data from the Internet. For example, the first object could be responsible for downloading data from the Internet. The second object might be responsible for running calculations on spreadsheets. The third object might be responsible for saving data to a database and running queries and so on. And all three of these objects may share a similar or the same named method, right? Let’s say all three of those objects had in their classes defined a method called work. Okay. So if we were to invoke work here for each of these, then each of these will be performing their own work in whatever way, shape or form.
Work is defined in their classes, and so it’ll be different behavior based on the object, even though the same method is being invoked. So all three of these objects have, for example, let’s just say the method work defined in their class. And we invoke work once here, and it’s going to run work for each of those objects. But the behavior of what work does is going to be totally different. And we’re going to get into more practical examples. I know this is just sort of a contrived example with vehicles. We don’t see any vehicles running around in our program. But this is just to simulate a simple example. So that’s one way of performing polymorphism, where you have a loop and you run one method. But that method applies to all different objects. All three objects. And these objects do different things based on whatever instructions are defined in their particular version of the Drive method. Another one is to have a method. Let’s just say perform tasks. Okay.
And this method takes some kind of object. It takes for example, let’s say it takes vehicle object. I just created this parameter vehicle object and so it could just perform vehicle object drive. Okay. And now I can just invoke this method anywhere where I want and pass in either a truck, a car or a motorcycle. And it’s going to invoke the drive method, regardless of what kind of vehicle it is, as long as it’s a vehicle that has a drive method in its class definition, it’s going to invoke that. So very similar. This is similar to what’s going on up there. It’s just that up there we have a loop defined here. We leave it up to the user of this method that wants to, for example, perform tasks. Let’s say they want to. Invoke this method, they would pass in a car or a truck or any other kind of object that complies with the signature of this method. Right? Now, one thing to keep in mind is that again, python is very flexible.
So it doesn’t warn you if we try to pass in some other object for perform tasks? Because I haven’t really told what vehicle object is. Python is not a type safe language, meaning we don’t enforce what type of object can go into the parameter here. So a person that may not be familiar with our code may invoke this method and pass some other kind of object in here. Let’s Say Object One Or Whatever, and let’s Just Say That This Is an object that is of type person, for example, and the person may not have researched what performed tasks actually does.
So if they pass in a person object in here and person obviously can’t really there’s no drive method defined on a person class. Let’s say then this is going to break our code, right? So I would say that handle polymorphism with a lot of care and try not to get too fancy with creating large hierarchies of classes and creating these sorts of abstractions. If you want to do that, make sure you give good comments inside the definition of the method as well as for any code that you write. Make sure you leave good comments so that the person that wants to use your method knows exactly how it should be used. Comments are extremely, extremely important, especially in Python, because it’s such a flexible language and you can pretty much do anything and you’ll find out when there’s a bug, when you run the code and it’ll crash because it’s not a type safe language. We can’t enforce the type of data that gets passed in to this method argument.
A user of this method could really pass in anything they want. Now, we can perform checks inside of the method with if else statements and check whether it’s a type vehicle, and if not, then return something else. But that gets a little hairy sometimes and you don’t want to make your programs overly complicated. All right. So with that being said, we’ve discuss two forms of polymorphism in the next lecture. There’s one more form that I want to talk about, and that is using abstract.