WEBVTT

1
00:00:00.350 --> 00:00:01.970
<v ->Hi guys, and welcome back.</v>

2
00:00:01.970 --> 00:00:03.800
In this video, we're going to talk about

3
00:00:03.800 --> 00:00:05.400
imports in Python,

4
00:00:05.400 --> 00:00:06.430
how to work with files,

5
00:00:06.430 --> 00:00:10.330
how to get code from another file into your main file.

6
00:00:10.330 --> 00:00:13.320
I've got two files now in my project,

7
00:00:13.320 --> 00:00:17.240
code.py and mymodule.py.

8
00:00:17.240 --> 00:00:19.890
I'm going to write some code in mymodule.py

9
00:00:19.890 --> 00:00:23.130
that I will then import into code.py

10
00:00:23.130 --> 00:00:24.513
so I can use it from there.

11
00:00:25.590 --> 00:00:27.070
So I've written a simple function

12
00:00:27.070 --> 00:00:29.600
that divides two parameters,

13
00:00:29.600 --> 00:00:34.600
and I'm also going to print mymodule.py colon

14
00:00:34.720 --> 00:00:36.257
and then, __name__.

15
00:00:38.027 --> 00:00:42.690
__name__ is a global variable in Python

16
00:00:42.690 --> 00:00:46.030
that changes depending on which file you're in.

17
00:00:46.030 --> 00:00:47.690
So it is a special variable

18
00:00:47.690 --> 00:00:49.950
because it will allow you to differentiate

19
00:00:49.950 --> 00:00:54.950
between the file you run and a file you import,

20
00:00:55.090 --> 00:00:56.560
and it also does a couple more things

21
00:00:56.560 --> 00:00:58.210
that we'll explain as we go along.

22
00:00:58.210 --> 00:01:01.530
So here in mymodule, I've defined a function,

23
00:01:01.530 --> 00:01:06.530
and I've also printed out the __name__ property,

24
00:01:06.720 --> 00:01:10.520
and I've also said that we're in mymodule.py there.

25
00:01:10.520 --> 00:01:14.403
So if I run this code right now,

26
00:01:15.950 --> 00:01:19.370
what you'll see is that you get mymodule.py,

27
00:01:19.370 --> 00:01:21.580
and then, you get dunder main.

28
00:01:21.580 --> 00:01:23.360
Instead of saying underscore underscore all the time,

29
00:01:23.360 --> 00:01:24.600
I'll just say dunder for now.

30
00:01:24.600 --> 00:01:27.490
That's the usual Python terminology.

31
00:01:27.490 --> 00:01:30.640
So you get mymodule.py and then dunder main.

32
00:01:30.640 --> 00:01:32.990
So evidently, dunder name

33
00:01:32.990 --> 00:01:36.500
must have equaled dunder main at the time of running.

34
00:01:36.500 --> 00:01:39.280
Otherwise, you wouldn't have got that printed out.

35
00:01:39.280 --> 00:01:42.460
So let's say that when you run a file,

36
00:01:42.460 --> 00:01:46.940
the dunder name variable equals dunder main

37
00:01:46.940 --> 00:01:48.920
because we've ran mymodule.py.

38
00:01:48.920 --> 00:01:51.130
That's why that value's there.

39
00:01:51.130 --> 00:01:53.970
If we go over to code.py now,

40
00:01:53.970 --> 00:01:58.610
we're going to do from mymodule import divide,

41
00:01:58.610 --> 00:02:02.460
and this is how you can import a specific thing

42
00:02:02.460 --> 00:02:04.050
from another file.

43
00:02:04.050 --> 00:02:05.650
So here, we're doing from

44
00:02:05.650 --> 00:02:08.470
and then the file that we wanna import from

45
00:02:08.470 --> 00:02:12.290
and then import and the thing that we wanna import.

46
00:02:12.290 --> 00:02:14.270
Alternatively, if you don't want to import

47
00:02:14.270 --> 00:02:17.270
a specific thing from the file,

48
00:02:17.270 --> 00:02:20.680
then you can just do import mymodule,

49
00:02:20.680 --> 00:02:24.380
and then, as usual, you would access the divide function

50
00:02:24.380 --> 00:02:27.800
inside mymodule by doing mymodule.divide.

51
00:02:27.800 --> 00:02:29.030
If you wanted to do that instead,

52
00:02:29.030 --> 00:02:30.280
that's also totally fine.

53
00:02:31.130 --> 00:02:32.410
There are some subtle differences

54
00:02:32.410 --> 00:02:33.830
between the two types of import,

55
00:02:33.830 --> 00:02:34.880
but they are subtle,

56
00:02:34.880 --> 00:02:36.490
so you won't come across them very often.

57
00:02:36.490 --> 00:02:38.370
We're not gonna cover them in this course.

58
00:02:38.370 --> 00:02:42.000
Now that we've imported the divide function from mymodule,

59
00:02:42.000 --> 00:02:45.970
we can use it as if it were defined inside this file,

60
00:02:45.970 --> 00:02:47.350
so I will do that.

61
00:02:47.350 --> 00:02:49.770
Then I'm going to run this file,

62
00:02:49.770 --> 00:02:52.900
and you see that we get two pieces of output now.

63
00:02:52.900 --> 00:02:55.940
We get mymodule.py is mymodule,

64
00:02:55.940 --> 00:02:59.770
and you get 5.0, which is the result of dividing this here,

65
00:02:59.770 --> 00:03:01.290
and here is the interesting part.

66
00:03:01.290 --> 00:03:05.300
Notice how earlier, mymodule.py printed out dunder main,

67
00:03:05.300 --> 00:03:06.950
but now, it has printed mymodule.

68
00:03:08.140 --> 00:03:12.100
That is because only the file you run is dunder main.

69
00:03:12.100 --> 00:03:16.470
So if we print dunder name here and we run this again,

70
00:03:16.470 --> 00:03:21.440
you'll see that you get dunder main printed out inside code,

71
00:03:21.440 --> 00:03:24.930
but mymodule.py is still printing out mymodule.

72
00:03:24.930 --> 00:03:27.200
So the file you run is dunder main,

73
00:03:27.200 --> 00:03:28.680
and as soon as you import other files,

74
00:03:28.680 --> 00:03:31.320
Python will name them according to their path.

75
00:03:31.320 --> 00:03:34.610
So mymodule here is at the top level of our folder,

76
00:03:34.610 --> 00:03:36.233
so the name will be mymodule.

77
00:03:37.490 --> 00:03:41.040
So how does Python know where mymodule is?

78
00:03:41.040 --> 00:03:43.470
Does it just look in the current folder?

79
00:03:43.470 --> 00:03:47.000
Well, the answer is in import sys.

80
00:03:47.000 --> 00:03:49.310
import sys allows you to use the sys module

81
00:03:49.310 --> 00:03:50.660
that comes with Python,

82
00:03:50.660 --> 00:03:53.510
and that unlocks some certain system functionalities,

83
00:03:53.510 --> 00:03:56.980
and one of them is sys.path.

84
00:03:56.980 --> 00:04:00.420
So sys.path is the import paths

85
00:04:00.420 --> 00:04:04.980
where Python will look in order to find files to import.

86
00:04:04.980 --> 00:04:06.950
So I'm gonna press Play now,

87
00:04:06.950 --> 00:04:08.420
and you can see that you've got

88
00:04:08.420 --> 00:04:11.973
a whole bunch of different paths here inside a list.

89
00:04:12.810 --> 00:04:15.890
The first path that Python is going to look at

90
00:04:15.890 --> 00:04:17.460
is the first one in this list,

91
00:04:17.460 --> 00:04:21.380
which, as you can see, is this 29_imports_in_python folder

92
00:04:21.380 --> 00:04:22.850
that we are currently in.

93
00:04:22.850 --> 00:04:25.880
So whenever you try to import something called mymodule,

94
00:04:25.880 --> 00:04:28.820
Python is going to go into this folder first

95
00:04:28.820 --> 00:04:32.040
and see if something called mymodule.py is in there,

96
00:04:32.040 --> 00:04:34.610
or, indeed, a mymodule folder,

97
00:04:34.610 --> 00:04:37.580
and if it is there, it will try to use that.

98
00:04:37.580 --> 00:04:40.410
If it's not, then it will go into the next path

99
00:04:40.410 --> 00:04:42.040
and then into the next one and so on.

100
00:04:42.040 --> 00:04:46.170
If it reaches the end and nothing was found for that name,

101
00:04:46.170 --> 00:04:48.550
then you'll get an error, an import error.

102
00:04:48.550 --> 00:04:53.160
For example, if I try to import sysasdf,

103
00:04:53.160 --> 00:04:55.290
you're going to get an import error

104
00:04:55.290 --> 00:04:58.493
saying ModuleNotFound, No module named sysasdf.

105
00:04:59.340 --> 00:05:01.460
These paths aren't defined in any specific order,

106
00:05:01.460 --> 00:05:05.450
so the first path is always the path of the file you ran.

107
00:05:05.450 --> 00:05:06.823
So here, we've ran code.py,

108
00:05:07.720 --> 00:05:11.230
so the first path is the path to code.py

109
00:05:11.230 --> 00:05:13.010
except, of course, the file name.

110
00:05:13.010 --> 00:05:14.810
So whenever you run a Python file,

111
00:05:14.810 --> 00:05:17.840
you will be able to import other Python files or folders

112
00:05:17.840 --> 00:05:21.410
inside the same folder that you ran.

113
00:05:21.410 --> 00:05:24.290
The second path, if defined,

114
00:05:24.290 --> 00:05:27.060
is an environment variable called PYTHONPATH.

115
00:05:27.060 --> 00:05:29.540
At the moment, we don't have a PYTHONPATH defined,

116
00:05:29.540 --> 00:05:31.510
so that's not there,

117
00:05:31.510 --> 00:05:33.920
and then, you've got all your other paths

118
00:05:33.920 --> 00:05:36.783
for your imports that are defined at a Python level.

119
00:05:37.760 --> 00:05:41.110
In UNIX systems, you can do export PYTHONPATH,

120
00:05:41.110 --> 00:05:43.230
and then, give it a path.

121
00:05:43.230 --> 00:05:46.263
For example, you can do /Users.

122
00:05:47.670 --> 00:05:49.780
Then, if you run this code again,

123
00:05:49.780 --> 00:05:53.660
you'll see that the second path now in sys.path

124
00:05:53.660 --> 00:05:56.220
is the /Users path.

125
00:05:56.220 --> 00:05:58.640
Again, the first path will always be

126
00:05:58.640 --> 00:06:01.610
the one that you currently ran your file in,

127
00:06:01.610 --> 00:06:05.250
and the second one will be your PYTHONPATH if it is defined,

128
00:06:05.250 --> 00:06:07.040
and finally, the rest of your paths.

129
00:06:07.040 --> 00:06:08.560
In Windows, instead of export,

130
00:06:08.560 --> 00:06:10.580
you'll have to use the keyword set

131
00:06:10.580 --> 00:06:13.270
to set an environment variable.

132
00:06:13.270 --> 00:06:15.930
Let's go back to importing mymodule,

133
00:06:15.930 --> 00:06:17.270
and now, from mymodule,

134
00:06:17.270 --> 00:06:20.170
we're going to import something in a folder.

135
00:06:20.170 --> 00:06:22.780
So here, in my project, I'm going to create a new folder.

136
00:06:22.780 --> 00:06:25.190
I'm gonna call it libs for libraries,

137
00:06:25.190 --> 00:06:26.230
and inside that folder,

138
00:06:26.230 --> 00:06:29.063
we're going to create a library called mylib.py.

139
00:06:30.023 --> 00:06:33.040
mylib.py is going to contain just mylib.py

140
00:06:33.040 --> 00:06:35.290
and then dunder name,

141
00:06:35.290 --> 00:06:38.450
just so you can see how the dunder name operates.

142
00:06:38.450 --> 00:06:42.123
Here, in mymodule, we're going to import libs.mylib,

143
00:06:43.940 --> 00:06:46.460
and then here, we're gonna import mymodule.

144
00:06:46.460 --> 00:06:49.493
So the imports go code imports mymodule,

145
00:06:49.493 --> 00:06:51.720
mymodule imports libs.mylib,

146
00:06:51.720 --> 00:06:53.850
and then, mylib prints out the name.

147
00:06:53.850 --> 00:06:56.040
Let's run this and see what happens.

148
00:06:56.040 --> 00:06:59.700
So as you can see, we got mymodule.py imported,

149
00:06:59.700 --> 00:07:02.600
and the name at the time was mymodule,

150
00:07:02.600 --> 00:07:05.270
and then, that imported mylib.py,

151
00:07:05.270 --> 00:07:07.900
and the name was libs.mylib.

152
00:07:07.900 --> 00:07:11.590
So again, it is the path that you use for importing

153
00:07:11.590 --> 00:07:12.753
that is relevant.

154
00:07:13.810 --> 00:07:17.220
If you're using Python 2, then this will not work

155
00:07:17.220 --> 00:07:19.080
because in some Python versions,

156
00:07:19.080 --> 00:07:23.120
you have to also create a dunder init file

157
00:07:23.120 --> 00:07:25.630
inside any folder that you wanna import from.

158
00:07:25.630 --> 00:07:27.790
So here in the libs folder,

159
00:07:27.790 --> 00:07:31.700
I have created a __init__ file.

160
00:07:31.700 --> 00:07:33.180
I would recommend that you get accustomed

161
00:07:33.180 --> 00:07:34.280
to creating those files

162
00:07:34.280 --> 00:07:36.360
because they are sometimes required.

163
00:07:36.360 --> 00:07:38.010
After doing all those imports,

164
00:07:38.010 --> 00:07:40.760
you can actually check sys.modules

165
00:07:40.760 --> 00:07:42.200
to see what's imported.

166
00:07:42.200 --> 00:07:47.200
So I will also import sys from here and press Play,

167
00:07:47.260 --> 00:07:49.330
and then, you can see that there's a bunch of things

168
00:07:49.330 --> 00:07:52.330
that have been imported at the time.

169
00:07:52.330 --> 00:07:57.180
So you have all of these built-in modules,

170
00:07:57.180 --> 00:08:00.860
including the sys module that has a bunch of other things,

171
00:08:00.860 --> 00:08:02.860
_frozen_importlib, and you know,

172
00:08:02.860 --> 00:08:04.170
there's loads of different ones

173
00:08:04.170 --> 00:08:06.730
that already come with Python you can use,

174
00:08:06.730 --> 00:08:09.400
and then, at the very end, you've got your own.

175
00:08:09.400 --> 00:08:12.121
So you have libs.mylib,

176
00:08:12.121 --> 00:08:14.670
libs, and mymodule,

177
00:08:14.670 --> 00:08:17.110
and these are all imported by the imports

178
00:08:17.110 --> 00:08:18.500
that we've written.

179
00:08:18.500 --> 00:08:21.050
So whenever you type another import

180
00:08:21.050 --> 00:08:22.530
somewhere else in your programme,

181
00:08:22.530 --> 00:08:24.690
Python is going to check these modules

182
00:08:24.690 --> 00:08:26.810
and see if that import is there,

183
00:08:26.810 --> 00:08:29.540
and if it is, then it's going to use that

184
00:08:29.540 --> 00:08:31.620
instead of trying to import again.

185
00:08:31.620 --> 00:08:32.980
Why does that matter?

186
00:08:32.980 --> 00:08:35.590
Because have you seen, when we import a file

187
00:08:35.590 --> 00:08:37.080
such as import mymodule,

188
00:08:37.080 --> 00:08:40.610
it runs through the file in order to be able to determine

189
00:08:40.610 --> 00:08:43.800
what is inside the file that we can use.

190
00:08:43.800 --> 00:08:46.710
So if you were to import the same thing many times

191
00:08:46.710 --> 00:08:49.460
and every time you ran that same thing,

192
00:08:49.460 --> 00:08:51.690
you might find that your code is running a lot of times

193
00:08:51.690 --> 00:08:53.880
over and over without achieving anything.

194
00:08:53.880 --> 00:08:55.860
That's why Python keeps track of the things

195
00:08:55.860 --> 00:08:57.330
that have already been imported,

196
00:08:57.330 --> 00:08:59.510
and if they have, you won't run through them again.

197
00:08:59.510 --> 00:09:01.750
You'll just be able to use the one that's already ran.

198
00:09:01.750 --> 00:09:03.250
Hopefully that makes sense.

199
00:09:03.250 --> 00:09:05.500
To recap, importing runs through a file

200
00:09:05.500 --> 00:09:08.210
and allows you to access the properties defined inside it.

201
00:09:08.210 --> 00:09:11.350
The dunder name variable is equal to dunder main

202
00:09:11.350 --> 00:09:13.180
in the file you run

203
00:09:13.180 --> 00:09:16.350
and is equal to the import path on other files,

204
00:09:16.350 --> 00:09:19.040
and you can import from files or folders

205
00:09:19.040 --> 00:09:22.840
as long as they are in your sys paths.

206
00:09:22.840 --> 00:09:24.620
Importing from a folder usually requires

207
00:09:24.620 --> 00:09:27.520
a dunder init.py file to be defined,

208
00:09:27.520 --> 00:09:30.040
especially in older Python versions.

209
00:09:30.040 --> 00:09:31.350
Thanks for joining me in this video.

210
00:09:31.350 --> 00:09:32.290
Hope it's been useful.

211
00:09:32.290 --> 00:09:33.740
I'll see you in the next one.

