Python Institute PCAP – Modules, Packages and Object Oriented Programming in Python Part 5
- Python Packages
Using Python modules. And all modules are is basically Python files with Python code in them. Another higher level way of organizing your code is into packages. And a package is basically just a collection of modules in directories that give it a sort of a package hierarchy. So you can have a folder within a folder within a folder that contains modules or Python files, and each of those folders can further have their own files in them. So hopefully you get the idea. So let’s go over an example of how that looks. So first what I’m going to do is, rather than creating a new package on our own, I’m going to actually download and install a Python package. And then we’re going to explore that package to see what it looks like so that you can get a better feel for what a package is in Python. Right? So I’m going to use a command line program known as Pip. Pip. And Pip is the de facto standard package management system used to install and manage software packages written in Python.
Okay. It stands for Python package installer. Now, I know Pip is not exactly ordered the same way as Python Package installer, but that’s what they chose to name it. So we’re going to use that. And if you downloaded Python correctly, you should have Pip as well as Pip Three in your computer if you have both versions of Python on your computer, python Two as well as Python Three. So since we’re using Python Three in this course, we’re going to use Pip Three in your command prompt, and then you type install, and after that, we give a particular package name.
Now, there’s a huge number of packages that do various things in Python, such as web development, data science, machine learning, all kinds of really cool stuff. So we’re going to download a package known as Pandas. P-A-N-D-A-S. So let’s do that. Pandas. And this is actually a Python data analysis library. It comes with a lot of functionality that you can use to crunch through various kinds of data structures. You can organize data into tables and that sort of thing, but not important to go over that right now, let’s install this Pandas package. I’m going to just hit enter, and now it’s going to start collecting whatever it needs to collect, and it’s going to download it from the publicly available repository that Pip downloads from. And so there we go. It says you are using Pip version. Yada, yada, yada.
However, you can ignore that warning for now. Notice where it installed some of these packages. And another thing to keep in mind is it has installed multiple packages. So there’s this thing called Pytz, there’s NumPy, there’s six, and so on. There’s a couple of things. And so it’s going into this Pandas folder that is going to reside in this particular directory. So let’s actually copy this. Let me expand it so that we can see the whole thing. I’m going to copy this directory location. As a matter of fact, it’s actually this one right here above where it has Python dot framework. So let’s just expand this further. And there you go. It goes into the Python 3. 8 site packages.
So let’s CD to that directory location by using the change directory command right here. And let’s hit enter. And now we’re in that directory location. Now, if we list the contents of this folder, if I do an LS, you’ll see some of the things, the packages that we have available to us. And lo and behold, here’s the Pandas package. Now all it is is a folder. So if I do a CD change directory and go into Pandas and do an LS to list the contents of the directory, you’ll see that there’s this file called init PY underscore underscore init PY, okay? As a matter of fact, all of these this is a particular file. Notice it has the PY extension. So there’s a file. But anything that doesn’t have a PY after it is going to be a directory here.
So such as API, arrays, compact errors, IO and so on. So let’s go into API, for example. So if I do change directory API and hit enter and then do an LS to list the contents of the directory, you’ll see again, there’s this init PY. All right, there’s another folder here called extensions. Let’s go into that folder, CD extensions. And then we do an LS. And lo and behold, there’s another init PY. So every folder that’s inside of a folder, when you’re trying to build a package in Python, it requires this init PY file, okay? And this file could be just left empty. You don’t need to have anything in this file. Just a file name needs to be there. That’s just how a package folder structure in Python is constructed. So we’ll go over an example of how to create our own package.
And then I’ll show you how you can utilize code that is residing in various folders within a package. We’ll look at that next. So let’s go over how to create a package. I’m going to open the finder window here, go to desktop. That’s where I have these two modules, the main module that we looked at and another module, PY. So these two modules, what I can do is organize it into packages. So let’s create a new folder here, and we’ll call it main underscore package, okay? And inside of this main package, I’m going to copy or move this main module into it. Now, right now all this is, is a folder that contains a Python file. It’s not legally a Python package just yet. To make it a package, what we’d need to do is create another file. And it would, of course, need to be in it PY. That file would need to reside in this main package. Folder.
And then officially, this would be considered a python package. So what I’m going to do is open another file in Sublime text, and I’m not going to put anything in this file. I’m just going to file save as, and I’m going to save this file in the main package folder. And we’ll call this of course, in it. Make sure you have double underscores first. So double underscores init, double underscore PY, okay? And save this in that folder location. And now this file has been saved. Now this is officially a python package. Now we’ll get into why, you know, why we can’t just leave files and folders. Because it’s just we’ll get into the design principles of how to organize your programs as they get larger and larger. You want to organize them in packages like this, but this is essentially how you create a package. Now to create another package within this package, we can actually create another folder. So right click in here and go to new folder. And we’ll call this sub underscore package.
And now I can use this another module. Let’s first move that into main package. So now in main package, we’ve got the main module and another module. Let’s move this another module into the sub package. There we go. And now in subpackage again, you guessed it, we need the init PY to turn this into an actual python package. So let’s create a new file and we’ll save this file as underscore underscore init underscore underscore PY. And that, of course, goes into the subpackage folder. Let’s save it. Let’s close this. And here’s our init PY. So now we’ve got this main package and we’ve got the sub package. So let’s show you how you can access the modules that reside in those packages.
So now back on my desktop, I’m going to create a new file. Let’s just open that in Sublime text, and I’m going to save this file on the desktop. And I’ll just call this program PY. It’s on the desktop. It’s outside of any of the packages that we created the main package, right? So let’s save it on the desktop. Now, if I want to utilize some of the code that’s in those packages, the way to do that is and the syntax is important. That’s why we’re going over it so that when you need to utilize code in larger software projects, you can import code that you need from packages. Let’s say we want to use the code that’s in the main package and that is called main module. If I want to access main module in program PY, the way I would do that is I type from main underscore package import and then specify the given module. And I think it’s called main module, right? Or the underscore. Let’s make sure. Yes, it’s underscore. You don’t need the PY.
Now, what do we import here? Well, let’s take a look at main module for a second, let’s open up main module. I’ll open that up in another file here in Sublime text. Now this main module, all it does is invokes the greet user function that’s defined in another module. So we need to first of all, maybe define a method here. We could define, we’ll call it main underscore funk. And then as the body of this function, it basically invokes greet user. Let’s see if this works. I’m going to save it and let’s close this file. And now to be able to use that, I could just do main module, main underscore module, main underscore funk. And so now I’m going to save this and let’s see if this runs. Now notice, keep in mind that we change the structure of those files a little bit. We put them in their packages, right? So let’s see if this works the way we have it. Let me zoom in a bit into this text editor. Let’s navigate over to the desktop. And now let’s run using Python three, the file called program PY, which is sitting on our desktop. Let’s run it and look, we’ve got an error. What does it say? It’s saying no module named another module. The reason is another module is not in the folder of the main module, is it? Right. Another module is in a sub package. It’s in a different package.
So what we would need to do is go into the main module and let’s do that. Let’s go into the main module file and we have to change this import statement. Now, generally using the from clause, we specify the particular module that we want and then the thing in the module that we want, whether it’s a class or a function or everything in the module. In this case, since we’re dealing with packages, we need to specify in the from statement here, we need to specify the package first. Okay? And so the way to do this is we specify the entire package structure. So let’s revisit that real quick just so that we don’t forget. Inside of main package we’ve got subpackage and the file that we actually want, the module that we actually want is another module PY. So another module PY resides in main package subpackage. Okay? That’s all you have to reference it.
So we do main underscore package, sub underscore package that goes in the from statement and an import here is where we actually do the import and that’s going to be another module. All right. Now with this syntax, we now use this another module in the actual function call. So we paste that here and dot so we do another module dot greet user, right? And this actually is, in my opinion, easier to read if you have a very large project and you have packages within packages. Within packages. It’s a good idea to have very explicitly named directory structures in your import statement. So I like this from main package. Okay, we got a main package, we got a sub package, and there could be many other sub packages. We would just have to dot through each one. So let’s say dot another sub package and then dot another sub package. However many nested structures you want, you can go into those packages by just doing a dot and going inwards like that.
So inside of subpackage is where we have the module of interest, and that module is called another module. So we import that and now we can access everything in the other module by of course referencing it here and then doing a dot greet user. All right, so by default, within the from clause, it expects a module here. But when you’re dealing with packages, you actually have to space state the packages here. This could get a little confusing. So understand you need to specify the packages here when you’re dealing with packages and then specify the module after the import. All right, so this should work. Now let’s save this file and let’s run it. So let’s run the same command, python three, program PY. Hit enter and there we go. Notice it says hello there, stranger from another file. Now, if we wanted to access the code that’s in another module directly in the program that’s on our desktop, let’s close this in the program that’s on our desktop.
Let’s open that up here called program PY. If I wanted to access the subpackage directly, what would I need to do? Well, I’ll do the same thing main package subpackage, make sure to spell that correctly and then import the another module. Okay. And so now using another module, I can of course do a dot greet underscore user. Is that the method function? Rather. Let’s double check in main package subpackage. I could just peek at this another module and yes, it’s called greet underscore user. So we’re calling that directly here in the program PY. All right, and so now if we run this again, we’ll get the same result. Let’s run it. And there we go. Hello there, stranger from another file. All right, so a little confusing for newcomers. So this is an important lecture. Understand it really thoroughly. When you’re dealing with just modules that are in the same folder, you could just do from, and then you specify the module name and then you import the class, the method, the function, whatever it is that you need to import there. But when you’re dealing with packages like we are here, you have to give the entire package structure. Okay? And that goes in the from clause like we have here. So why do we organize our projects and packages? Well, that’s the de facto standard when working with large projects. And you can see how much code organization we can enforce here when we specify the particular package hierarchy here and then specify the thing that we want to import.
Everything is sort of attached together in a project tightly structured so that files don’t go flying around all over the place. If we just had folders and there was no package structure, someone could just move a particular file in another folder and then you’d have a nightmare going through, where did that file go? Somebody just moved to another folder. But if you have this specified in the code, where you have this is a parent package, this is the sub package and other child packages and so on. And this module is coming from this particular exact location. That’s why for large projects, packages are crucial.
- Understanding the if __name__ == __main__ Syntax
Your module and calling some of the methods or functions rather that are defined in it. But you might also want your module to run directly and do something if somebody tries to run it directly. Let me give you an example. Let’s say that we have, I’m going to create a new file here and I’m going to name this file. We’ll save it as Process dot PY, and we’re going to save it directly on our desktop so there’s not in a package or anything and I’ll create a new file. We’ll save this on the desktop as well. We’ll call this Process Runner PY, okay, so we’ve got the process and then we’ve got this Process Runner. And let’s say that the Process Runner is supposed to import the process and invoke some run method on it, right? So let’s create some methods in process PY. So we can have a method called, for example, Run. And this could do something such as download data from the Internet or carry out some process. So to keep it simple, I’m just going to say process started running, okay, whatever the process is. And then this process module can also have a shutdown method, right? So we can do shut down. Let’s say we say that the process is shutting down and then we can also have something called email admin. We’ll define what email admin is in a little bit.
Now, if I give this file to somebody and they run it directly, it’s not going to do anything. Let’s do that. Let’s go to the desktop and let’s try to run the Process PY file. Notice if you run it, nothing happens. These methods are defined, nothing is being invoked right now. You can have a very large module with many, many methods and classes and so on, but there may not even be a starting point. You won’t know what code runs first. So you could have a starting point to a module, okay? And so to define a starting point for a given module, there’s a special syntax and as soon as you type if the IntelliSense in Sublime text or any other tool will probably give you a syntax like this by default. And what this is saying is that if this is a reserved variable in the Python language, underscore underscore name, underscore underscore, and this is saying that if this variable is assigned this value, then carry out whatever the instructions are, all right? And it automatically populates this main function call here. We don’t need that. So let’s say that if somebody tries to run this script directly, we’d like to email the admin.
So now the email admin could have we could just say that you violated some process and violation noted emailing admin, whatever it is, right? The idea is that there’s now a starting point for this process PY and that is right here. If somebody tries to run this file directly, all that’s going to happen is the code that’s written that’s inside of this if block, okay? And you can have multiple things going on here. You can be logging to files. You could be emailing other people, whatever it is, if this file is run directly, the code that’s in this if block and it could be many, many lines of code will get run. So in this case, if we want to make sure no one runs this file directly, we have this email admin that gets invoked, right? So let’s try this again. I’m going to run the same file, python three, process QA. Make sure you save that file. Let’s hit run and boom. There you go. Notice violation noted emailing admin. Now this is of course one use case, right? If we don’t want this file to be run, that’s what I’m kind of trying to simulate here. But let’s say this file is supposed to be run. We’d like for the ability to run this file directly. And it may be a complicated process. Let’s say we have the run, we have the shutdown, and we have other processes. Let’s do that. Let’s define another method here called Start task underscore one. And we can say started Task One, whatever the task is.
And then we can have a similar thing for start task Two, right? Let’s change that to Two, and let’s change this to two. And now to run this file correctly, let’s say if we want someone to be able to run this file, we want to of course, code out the order in which these functions should run. So first we’d like the run method to be executed. Then we’d like the Start task One to be executed. And then we want Start Task Two to be executed, right? And then finally we can have a shutdown thing, right? This complicated series of steps now, of course is not complicated by any means, but let’s just imagine that this is a very large file with a bunch of functions that do a variety of things. Now all of a sudden, this file is much more digestible. Anyone can look at this main line right here. This is the starting point of the application.
And see that, okay, this task supposed to run first. This task is supposed to run second, and so on. And then at the end, we shut down if someone was to run this directly. So let’s try that. And of course, you’ll see process started running task one. Task two, shutting down. Okay, that works. Now this is a self running module because we have this special line right here. But we can also have this module be an import. And in that case, we don’t want this code to be running if we import this module. So let’s try to import it. We could do from process import, and then we can import the various functions. So let’s say we want to import, run, and shut down. And then we can actually invoke run as well as shut down. And so now let’s try to run the Process Runner.
We do Python Three and then process runner PY. Let’s hit enter. And there we go. Process started running. Process is shutting down. But it didn’t run all the other commands, right? It didn’t run task one, task two, or anything. Oh, and by the way, I don’t know if I mentioned this to you, you can actually do an Asterisk here. And that will import everything, all the classes, all the functions, all the variables that may be defined in this particular module. Okay, this code should still run. Let’s test if that’s true. I’m going to just rerun this same Process Runner PY the way it was. And there we go. It runs those methods, or functions, rather methods. Again, just a reminder, methods are supposed to be referred to the functions that are defined inside of classes. And these are just functions that are not part of any class. They’re just defined as part of a script or module. So hopefully you get the idea. This process PY is a file that could be run directly because we have this line of code, or it can also be imported like we’re doing here. And in the case that we import, all of the other processes don’t run just the ones that we want. So meaning this code does not run if we’re using that file as an import. So every programming language out there has a way of specifying a starting point of any program or script.
And in Python, that’s this thing right here. Okay, so what does this mean? Let’s break this down a little bit. Why such a cryptic syntax? You have underscore underscore name, underscore underscore main. What does this even mean? Well, first of all, underscore underscore name, the reason why they left these underscores is so that it’s not easy for you to overwrite it, right? Because you might define a variable called name and you might just overwrite this. But since this is underscore underscore, you won’t have to worry about violating that. Now, to better understand this if statement, what is going on is the Python interpreter actually assigns a particular value to this name variable. As soon as this script is used, this module is used whether as an import or directly. So what happens is when we try to run this file directly, the interpreter actually takes this variable name called Name, and it assigns it the main value right here.
Okay? Even if this line was not there, let me cut this out the way the script is right now. If I try to run it in the background, what happens is Python, the Python interpreter takes a special variable called underscore underscore name, underscore underscore, and assigns it the value main. Okay, I don’t have that code there, but that’s what happens in the background. So as soon as it does that and before the script is about to run. What the interpreter does is it says, okay, now that my name variable is assigned the value main. Let’s see if there’s there’s a name variable with the value main in this file. If there isn’t, it would just execute the code the way it’s defined right here, whatever is in the code. But if it is defined in our case like this, then it would just, of course, run those instructions.
It run, run, start task two and then shut down. Now, when you import the module, like we are in process runner, the Python interpreter does not assign the name variable in the process any value. So what that means is the code that’s in here is not even going to run because this if check will fail. Because when you import it, the main variable will not be assigned this main value. Okay, hopefully that makes sense. That’s just getting into the nitty gritty of things of how the Python interpreter assigns this special variable, this value when this file is run directly and when it doesn’t assign this value, when the module.
- Section 5 Assignment
And this is just one assignment, but we have to write some code to practice object orientation. Okay, so there’s going to be multiple lines of code here, so make sure you’re on section five in your assignments project. And this is the one and only assignment in that section for now. I may add some more later to the course. So what does it say? It says, define a class hierarchy representing animals with a parent class, animal and a child child classes such as dog, fish, and bird. So we got three child classes and one parent class called animal. So each subclass or child class of animal should have a name and an age and should have two methods defined in it, which are move and eat. Okay? The move method needs to be specific for a given animal. So a fish would swim, a bird would fly, a dog would run, for example. Those are specific move methods, whereas the eat method should be generic.
So it could just say animal eating, and it would be the result of invoking the eat method on each of the objects of dog, fish and bird. The methods don’t need to do anything except print information about who is doing what. Okay? So when you invoke the eat method, it should just print out that the animal is eating. If you invoke the move method, it should just say that the dog is running or the fish is swimming and so on. All right? And after creating the class hierarchy, create instances of each of these three animals dog, fish and bird and make them eat and move. Okay, so why don’t you pause the video now and try this out on your own and then you can resume to watch my solution. All right, welcome back. Hopefully that wasn’t too difficult. So first things first, we need to create the animal class, which is going to be the parent class. So we’ll just use class, and then we have to specify animal. Make sure the first character is uppercase because that’s the naming convention when you create classes. And then we’re going to need a constructor here. So we’ll say def.
We’re defining a constructor and it’s going to be the in it method. And like I said, each animal is going to have a name as well as an age, but we’ll make that specific in the actual subclasses. We don’t have to make that part of the animal classes. It’s just a generic top level implementation of an animal. So here I’m just going to print animal constructed. All right, so the animal has been created and then I’m also going to have a move method, which is just going to say Animal moving. And then I’ll have a similar thing for the eat method, which is going to say Animal eating. So this is the top level generic implementation. Now let’s go into the specific animals. So the first class that I’ll work on is let’s say bird, make sure it’s capital and it is a subclass of animals.
So we need to make sure it inherits from the animal class. We put that in parentheses and then we need the constructor. And so that should be straightforward. You already know how to do this. So we have the self first and then we specify the age and then the name and so on. So age and then the name of the animal. I’ll just actually make it specific and say bird age and bird name. These are the names of the arguments. It does not matter what you call these, okay? What matters is self, age and self name. These are the actual instance variables that belong to a given instance of bird. And the argument names, whatever you call them, are going to be assigned to each of those instance variables. Now, one quick thing to note here. Notice it’s highlighting the init method. There must be some issue here. Let’s hover our mouth here and see what it says. Call to the init of superclasses missed. So what is this saying? It’s saying that you’re trying to create a bird. But what is a bird?
A bird is an animal. So you have to first create the animal in order to be able to create a bird. So all that requires is doing animal init and passing in self like that. And this line of code will create the animal instance and we’ll give the specific animal bird the age and name, right? So because bird is an animal, you can’t have a bird without it being an animal first, right? So that is exactly why we need this line. Keep in mind, we’re not creating two animal objects. We’re saying that we want to create a bird and it is an animal. So let’s make sure it is an animal first and then we assign it the age and name. Okay? So that’s the constructor for the bird. And then I’ll have a method for eating and move. So as a matter of fact, in the instructions, I think it says the move method needs to be specific for a given animal, whereas the eat method should be generic for all animals.
So we’ve got a generic eat animal eating method up here, right? So we don’t need to define the eat method here for the bird because we’re going to be utilizing the generic animal eat method. So all I need to define here is the move method. So animal moving, right? So for this, it’s going to be bird. Let’s just say print bird flying because this needs to be specific to a bird. Now that’s really all we need. As a matter of fact, we could just copy most of this for the rest of the animals. So that’s a bird. Now let’s do the same thing for fish. Make sure it’s capital F. That’s the naming convention. And here we can say fish swimming. All right? And that’s the only difference between a bird and a fish. For our example here and again, the fish is going to borrow the animals eat method. When we invoke a fish to eat or when we invoke a bird to eat, it’s going to borrow the animals implementation of the eat because that’s what I said in the instructions. We want to utilize a generic eat method. So we’ve got the bird, we’ve got the fish. Let’s just put a couple of spaces here so we can differentiate between these classes. There’s the parent class, there’s the child class bird, and this is the child class fish. We need one more for the dog. So we’ll paste that down here and we’ll change this to dog. And we’ll say dog running and that’s it. Now the last part of this is that after creating the class hierarchy, create instances of each of the three animals, dog, fish and bird and make them eat and move. So all we have to do is create an instance of let’s start with the dog. So we’ll say my dog is equal to dog. And then we give the dog the age. Let’s say he’s three years old and the name Wolfie. And then we can say my dog move. And we’ll also make the dog eat. We’ll do a similar thing for the rest of the animals.
Let’s first run this. So notice it’s animal constructed because dog is an animal. And this is of course coming from the parent class. Remember, we printed in the constructor up here in the animal class, animal constructed. So a dog is an animal, so it is being constructed because it inherits from the animal class. And we are also invoking the parent constructor here. So animal constructed, that’s where that comes from. And then it says dog running. And the eat method is being borrowed or inherited from the parent class, which is the animal class. So it’s just going to say animal eating. It’s utilizing the generic animal eat method, right? So we’ll do a similar thing for the rest of the types of objects. So we have the dog here, let’s make this fish.
And we’ll say the fish is one year old and we’ll call him Nemo. And we’ll do a similar thing for the last type of animal we have, which is the bird. And we’ll say that the bird is three years old and his name is Jojo. Okay? And so let’s run this. And so you’ll see for each of these instances it constructs an animal and then the animal is either a dog or a fish or whatever. So it says dog running for the dog, animal eating for the dog, for the fish, fish. It does the same thing, fish swimming, animal eating for the bird, bird flying, animal eating. So hopefully you get the idea. So if you got this far, great, you understand that you can inherit methods from parent classes and how you can create instances of each of these classes.