-: Hi guys, and welcome back.
In this video, we're going to talk about
imports in Python,
how to work with files,
how to get code from another file into your main file.
I've got two files now in my project,
code.py and mymodule.py.
I'm going to write some code in mymodule.py
that I will then import into code.py
so I can use it from there.
So I've written a simple function
that divides two parameters,
and I'm also going to print mymodule.py colon
and then, __name__.
__name__ is a global variable in Python
that changes depending on which file you're in.
So it is a special variable
because it will allow you to differentiate
between the file you run and a file you import,
and it also does a couple more things
that we'll explain as we go along.
So here in mymodule, I've defined a function,
and I've also printed out the __name__ property,
and I've also said that we're in mymodule.py there.
So if I run this code right now,
what you'll see is that you get mymodule.py,
and then, you get dunder main.
Instead of saying underscore underscore all the time,
I'll just say dunder for now.
That's the usual Python terminology.
So you get mymodule.py and then dunder main.
So evidently, dunder name
must have equaled dunder main at the time of running.
Otherwise, you wouldn't have got that printed out.
So let's say that when you run a file,
the dunder name variable equals dunder main
because we've ran mymodule.py.
That's why that value's there.
If we go over to code.py now,
we're going to do from mymodule import divide,
and this is how you can import a specific thing
from another file.
So here, we're doing from
and then the file that we wanna import from
and then import and the thing that we wanna import.
Alternatively, if you don't want to import
a specific thing from the file,
then you can just do import mymodule,
and then, as usual, you would access the divide function
inside mymodule by doing mymodule.divide.
If you wanted to do that instead,
that's also totally fine.
There are some subtle differences
between the two types of import,
but they are subtle,
so you won't come across them very often.
We're not gonna cover them in this course.
Now that we've imported the divide function from mymodule,
we can use it as if it were defined inside this file,
so I will do that.
Then I'm going to run this file,
and you see that we get two pieces of output now.
We get mymodule.py is mymodule,
and you get 5.0, which is the result of dividing this here,
and here is the interesting part.
Notice how earlier, mymodule.py printed out dunder main,
but now, it has printed mymodule.
That is because only the file you run is dunder main.
So if we print dunder name here and we run this again,
you'll see that you get dunder main printed out inside code,
but mymodule.py is still printing out mymodule.
So the file you run is dunder main,
and as soon as you import other files,
Python will name them according to their path.
So mymodule here is at the top level of our folder,
so the name will be mymodule.
So how does Python know where mymodule is?
Does it just look in the current folder?
Well, the answer is in import sys.
import sys allows you to use the sys module
that comes with Python,
and that unlocks some certain system functionalities,
and one of them is sys.path.
So sys.path is the import paths
where Python will look in order to find files to import.
So I'm gonna press Play now,
and you can see that you've got
a whole bunch of different paths here inside a list.
The first path that Python is going to look at
is the first one in this list,
which, as you can see, is this 29_imports_in_python folder
that we are currently in.
So whenever you try to import something called mymodule,
Python is going to go into this folder first
and see if something called mymodule.py is in there,
or, indeed, a mymodule folder,
and if it is there, it will try to use that.
If it's not, then it will go into the next path
and then into the next one and so on.
If it reaches the end and nothing was found for that name,
then you'll get an error, an import error.
For example, if I try to import sysasdf,
you're going to get an import error
saying ModuleNotFound, No module named sysasdf.
These paths aren't defined in any specific order,
so the first path is always the path of the file you ran.
So here, we've ran code.py,
so the first path is the path to code.py
except, of course, the file name.
So whenever you run a Python file,
you will be able to import other Python files or folders
inside the same folder that you ran.
The second path, if defined,
is an environment variable called PYTHONPATH.
At the moment, we don't have a PYTHONPATH defined,
so that's not there,
and then, you've got all your other paths
for your imports that are defined at a Python level.
In UNIX systems, you can do export PYTHONPATH,
and then, give it a path.
For example, you can do /Users.
Then, if you run this code again,
you'll see that the second path now in sys.path
is the /Users path.
Again, the first path will always be
the one that you currently ran your file in,
and the second one will be your PYTHONPATH if it is defined,
and finally, the rest of your paths.
In Windows, instead of export,
you'll have to use the keyword set
to set an environment variable.
Let's go back to importing mymodule,
and now, from mymodule,
we're going to import something in a folder.
So here, in my project, I'm going to create a new folder.
I'm gonna call it libs for libraries,
and inside that folder,
we're going to create a library called mylib.py.
mylib.py is going to contain just mylib.py
and then dunder name,
just so you can see how the dunder name operates.
Here, in mymodule, we're going to import libs.mylib,
and then here, we're gonna import mymodule.
So the imports go code imports mymodule,
mymodule imports libs.mylib,
and then, mylib prints out the name.
Let's run this and see what happens.
So as you can see, we got mymodule.py imported,
and the name at the time was mymodule,
and then, that imported mylib.py,
and the name was libs.mylib.
So again, it is the path that you use for importing
that is relevant.
If you're using Python 2, then this will not work
because in some Python versions,
you have to also create a dunder init file
inside any folder that you wanna import from.
So here in the libs folder,
I have created a __init__ file.
I would recommend that you get accustomed
to creating those files
because they are sometimes required.
After doing all those imports,
you can actually check sys.modules
to see what's imported.
So I will also import sys from here and press Play,
and then, you can see that there's a bunch of things
that have been imported at the time.
So you have all of these built-in modules,
including the sys module that has a bunch of other things,
_frozen_importlib, and you know,
there's loads of different ones
that already come with Python you can use,
and then, at the very end, you've got your own.
So you have libs.mylib,
libs, and mymodule,
and these are all imported by the imports
that we've written.
So whenever you type another import
somewhere else in your programme,
Python is going to check these modules
and see if that import is there,
and if it is, then it's going to use that
instead of trying to import again.
Why does that matter?
Because have you seen, when we import a file
such as import mymodule,
it runs through the file in order to be able to determine
what is inside the file that we can use.
So if you were to import the same thing many times
and every time you ran that same thing,
you might find that your code is running a lot of times
over and over without achieving anything.
That's why Python keeps track of the things
that have already been imported,
and if they have, you won't run through them again.
You'll just be able to use the one that's already ran.
Hopefully that makes sense.
To recap, importing runs through a file
and allows you to access the properties defined inside it.
The dunder name variable is equal to dunder main
in the file you run
and is equal to the import path on other files,
and you can import from files or folders
as long as they are in your sys paths.
Importing from a folder usually requires
a dunder init.py file to be defined,
especially in older Python versions.
Thanks for joining me in this video.
Hope it's been useful.
I'll see you in the next one.