Instructor: Let's learn about different ways
that we can actually import these modules.
Up until now, we've only learned about import
but sometimes things can get pretty hectic.
For example, we can actually have another package
inside of another package.
If, for example, I create a New folder here
and say, new Python package,
we'll call this more shopping, click Okay.
You see that I've initiated another package
inside of a package that has its own init file.
And let's move this now to let's do Refactor, Move,
and we'll move it inside of the more shopping folder.
So, I'll say more shopping.
If I click okay, you'll see that I've moved
this module over here.
So, I have a package inside of a package.
And the way we would access this
is to say simply shopping dot more
shopping dot shopping cart.
And let's copy that over and do the same here.
And now when I click run, you'll see that it still works.
But this is getting a little bit too crazy.
You can imagine as we have more and more packages
that we constantly have to do this dot this dot
and this is getting a little too long and ugly.
So, how can we better this?
Well, one way of doing this in a cleaner fashion
is to do something like this.
Instead of saying import, we say from this part,
I wanna import the function.
So, here I'm saying, hey, from package name,
package name, module, import whatever function I want.
In our case, we want to import the buy function.
So, you see here, I can just do that
and in my code I can just run buy
as if it was part of this main file.
If I run this, you'll see that it still works.
Awesome.
So, that's definitely cleaner.
And we can do this with utility as well.
I can say from utility import
and actually import the two files or the two functions.
So, that is multiply and if we want another function,
we can just add a comma and say divide.
So, now we can print apple
or buy apple as well as divide,
let's say five by two.
And we can also multiply.
Oh and make sure it's a comma here
'cause it is a function like this.
So that if I run this, you'll see that.
There we go.
This works as well.
So, this is a really nice way to clean up your code.
You can also do something like this
where you say from package name, package name
and then import the entire module.
So, let's say I want to import the shopping cart module.
I can say import.
So package dot package or you could have just
had have done one package
and import the actual module shopping cart.
So, now I would access it like this, shopping cart dot bye.
And this is going to work as well.
Perfect.
Now, the reason you might wanna
do this instead of what we had before
is that sometimes you can get named collisions.
Let me show you.
Let's say I had a print
and then in here we use the max function,
which gives us, it's a built-in function.
We give it an iterator, and it finds the max for us.
So, that if I run this, you'll see that the max
in this list is three.
Well, imagine in our utility function,
we have a let's say instead of divide
or we add a max that simply says returns and oops.
Well, if I go back to my main dot py
and get max as my function, and I click run,
well you see, I get an error.
I get max takes zero positional arguments,
but was given but one was given.
Because now max doesn't mean what we thought we meant,
at least in this file.
We've imported max and well
max is a whole different function now.
So, we can actually override existing functions.
So, by using something like this, shopping cart,
we make sure that we have only one case
that we might have name collision
but all the properties or all the methods
that shopping cart has are connected to shopping cart.
So, instead of having multiple functions
that could be overridden, I only have one namespace.
And by the way, this is also one of the reasons
that I don't recommend doing something like this.
You can actually do import star.
And what this says is, hey,
from the utility module, import everything.
And when you do that, you'll see that once again,
we get an error, because it imports the max as well.
And because we don't even know
what's being imported right now, we can't see it.
We have to go to the file to see it.
When we get an error like this,
we're be like, mm, what's going on?
I thought max is working, and it's because of this line.
So, it's always good to be explicit
and say exactly what you wanna import.
But let's remove max for now.
But as you can see,
modules can be imported in different ways.
My recommendation is to always be explicit
and say exactly what you want to import.
And the format usually follows
either using the import statement,
followed by the package dot module or import the module.
Or you can do the from statement
to give it package, sub-package and module if you want.
Or you can do module and then saying import
and the specific function or the actual module itself.
Many ways of doing it depending on your need.
The key takeaway here is that modules
and packages help us have good engineering practices
and build big projects in an organized fashion,
yet still have all these files talk to each other.
All right, that was a lot.
Let's learn more in the next video.