1
1

00:00:00,630  -->  00:00:02,750
<v ->Hi guys and welcome back. In this video,</v>
2

2

00:00:02,750  -->  00:00:05,663
we're going to talk about relative imports in Python.
3

3

00:00:05,663  -->  00:00:07,600
This is something that's really confusing
4

4

00:00:07,600  -->  00:00:10,200
for new Python beginners, and to be honest,
5

5

00:00:10,200  -->  00:00:11,880
it's a bit weird.
6

6

00:00:11,880  -->  00:00:14,260
And you're not going to be using them very much at all
7

7

00:00:14,260  -->  00:00:15,580
but I just wanted to talk about them
8

8

00:00:15,580  -->  00:00:17,680
so that you all use them precisely
9

9

00:00:17,680  -->  00:00:19,330
because they work very differently
10

10

00:00:19,330  -->  00:00:21,540
than what you might expect.
11

11

00:00:21,540  -->  00:00:24,750
What I've got here is four files now.
12

12

00:00:24,750  -->  00:00:29,140
I've got code, and mymodule in the same folder.
13

13

00:00:29,140  -->  00:00:34,140
Then we've got our libs folder that contains mylib.
14

14

00:00:34,790  -->  00:00:37,150
And then we've got our operations folder
15

15

00:00:37,150  -->  00:00:39,540
that contains operator.
16

16

00:00:39,540  -->  00:00:44,493
So code imports mymodule, mymodule imports libs.mylib,
17

17

00:00:45,470  -->  00:00:49,950
and mylib imports libs.operations.operator.
18

18

00:00:49,950  -->  00:00:52,290
And each one prints out their name.
19

19

00:00:52,290  -->  00:00:57,290
So if we press play right now, what you get back is--
20

20

00:00:57,680  -->  00:00:59,950
Well first of all, something important to note is that--
21

21

00:00:59,950  -->  00:01:01,170
I may not have mentioned it in the last video,
22

22

00:01:01,170  -->  00:01:04,010
is that when you run the import,
23

23

00:01:04,010  -->  00:01:06,130
that immediately jumps into the next file
24

24

00:01:06,130  -->  00:01:07,180
and starts running it.
25

25

00:01:07,180  -->  00:01:10,980
So of course, code.py imports mymodule
26

26

00:01:10,980  -->  00:01:12,820
so that stops code.py from running
27

27

00:01:12,820  -->  00:01:16,470
and Python jumps to mymodule. This imports mylib.
28

28

00:01:16,470  -->  00:01:18,440
So this stops running and jumps to mylib.
29

29

00:01:18,440  -->  00:01:20,250
This imports operator so that stops running
30

30

00:01:20,250  -->  00:01:23,420
and jumps to operator, and that prints.
31

31

00:01:23,420  -->  00:01:27,100
Then we go back to mylib and then we print,
32

32

00:01:27,100  -->  00:01:29,820
then we go back to mymodule, then we print,
33

33

00:01:29,820  -->  00:01:31,600
then we go back to code and then we print.
34

34

00:01:31,600  -->  00:01:33,530
So that's why the order here is reversed
35

35

00:01:33,530  -->  00:01:35,730
from the order in which the files are running.
36

36

00:01:35,730  -->  00:01:38,250
Code is running first but that prints out last
37

37

00:01:38,250  -->  00:01:42,200
because of that tree of imports that's going on.
38

38

00:01:42,200  -->  00:01:44,530
So this is not relative imports.
39

39

00:01:44,530  -->  00:01:48,600
These are just absolute imports where you have to define
40

40

00:01:48,600  -->  00:01:50,350
the path that you're importing from.
41

41

00:01:50,350  -->  00:01:55,180
So here and the path is libs.operations.operator
42

42

00:01:55,180  -->  00:01:58,640
and we're doing from libs.operations import operator,
43

43

00:01:58,640  -->  00:02:02,980
or you could do import libs.opererations.operator
44

44

00:02:02,980  -->  00:02:04,290
if you preferred, although then
45

45

00:02:04,290  -->  00:02:06,020
you would have to access things like
46

46

00:02:06,020  -->  00:02:08,980
libs.operations.operator.divide.
47

47

00:02:08,980  -->  00:02:13,270
If a divide function was defined inside that file,
48

48

00:02:13,270  -->  00:02:14,103
which it's not.
49

49

00:02:14,103  -->  00:02:15,910
At the moment, nothing's defined inside these files.
50

50

00:02:15,910  -->  00:02:17,990
They're just printing out their names.
51

51

00:02:17,990  -->  00:02:20,870
So that is absolute imports.
52

52

00:02:20,870  -->  00:02:23,250
Let's talk about relative imports.
53

53

00:02:23,250  -->  00:02:27,330
A relative import is one that can import
54

54

00:02:27,330  -->  00:02:31,900
from the current folder that the file is in.
55

55

00:02:31,900  -->  00:02:36,730
But it cannot import unless there is a folder name
56

56

00:02:36,730  -->  00:02:39,950
in the import path, in the module path.
57

57

00:02:39,950  -->  00:02:42,784
So, here's what that means.
58

58

00:02:42,784  -->  00:02:46,160
Libs.mylib when it prints out the name
59

59

00:02:46,160  -->  00:02:49,190
you can see that there is a folder inside the import path
60

60

00:02:49,190  -->  00:02:51,530
that is separated from other things in the path
61

61

00:02:51,530  -->  00:02:53,390
by a full stop, a period.
62

62

00:02:53,390  -->  00:02:55,250
So here you've got the libs folder
63

63

00:02:55,250  -->  00:02:57,370
and inside it you've got the mylib file.
64

64

00:02:57,370  -->  00:02:58,550
You can tell this is the file
65

65

00:02:58,550  -->  00:03:02,620
because it's the last thing in the import.
66

66

00:03:02,620  -->  00:03:05,890
Similarly, the operator.py has the file operator,
67

67

00:03:05,890  -->  00:03:07,180
that's where we're importing from
68

68

00:03:07,180  -->  00:03:10,360
and two folders, operations and libs.
69

69

00:03:10,360  -->  00:03:13,610
So, from these two you can do relative imports
70

70

00:03:13,610  -->  00:03:15,200
because there is a folder.
71

71

00:03:15,200  -->  00:03:17,270
From these two you cannot do relative imports
72

72

00:03:17,270  -->  00:03:19,080
because there's no folder.
73

73

00:03:19,080  -->  00:03:20,590
So let me show you what happens
74

74

00:03:20,590  -->  00:03:22,490
if you try to do a relative import
75

75

00:03:22,490  -->  00:03:24,640
and you don't have a folder.
76

76

00:03:24,640  -->  00:03:26,470
In order to do a relative import
77

77

00:03:26,470  -->  00:03:28,680
you need to use the from syntax.
78

78

00:03:28,680  -->  00:03:33,420
So you can do from .mymodule import divide let's say
79

79

00:03:33,420  -->  00:03:36,173
and I'm going to just add a divide function here.
80

80

00:03:38,780  -->  00:03:40,660
So (mumbles) divide function there it doesn't do anything
81

81

00:03:40,660  -->  00:03:44,220
and we're gonna try to import it from .mymodule.
82

82

00:03:44,220  -->  00:03:47,080
So what that means is from the current folder
83

83

00:03:47,080  -->  00:03:51,090
look at the mymodule file and import the divide function.
84

84

00:03:51,090  -->  00:03:56,090
So that makes sense because mymodule is in the same folder
85

85

00:03:56,720  -->  00:04:00,200
as code.py. You can see down here they're in the same folder
86

86

00:04:00,200  -->  00:04:02,160
so they should be fine.
87

87

00:04:02,160  -->  00:04:04,880
But when you try to do that,
88

88

00:04:04,880  -->  00:04:09,880
what it does is it tries to import from __main.mymodule.
89

89

00:04:12,230  -->  00:04:16,270
So as you can see because the name of this file was __main
90

90

00:04:16,270  -->  00:04:18,270
and it doesn't have a folder,
91

91

00:04:18,270  -->  00:04:21,890
it tries to import from the current place it's in
92

92

00:04:21,890  -->  00:04:24,460
and Python won't let you do that.
93

93

00:04:24,460  -->  00:04:28,120
If you are importing from the file you run,
94

94

00:04:28,120  -->  00:04:31,300
you can't use relative imports.
95

95

00:04:31,300  -->  00:04:36,300
Going into mymodule.py you could do from .libs import mylib
96

96

00:04:37,090  -->  00:04:39,710
and what that's going to do is it's going to try to access
97

97

00:04:39,710  -->  00:04:43,010
the libs folder inside the current folder,
98

98

00:04:43,010  -->  00:04:44,980
that's what the dot means.
99

99

00:04:44,980  -->  00:04:47,523
But again, if you try to run this code,
100

100

00:04:48,570  -->  00:04:51,370
you're going to get that you attempted a relative import
101

101

00:04:51,370  -->  00:04:54,830
with no known parent package.
102

102

00:04:54,830  -->  00:04:58,770
Again, mymodule has no information about the folder it's in
103

103

00:04:58,770  -->  00:05:01,713
so Python can't do a relative import from it.
104

104

00:05:02,890  -->  00:05:05,760
I'll show you again these paths here,
105

105

00:05:05,760  -->  00:05:07,270
because what you've got--
106

106

00:05:07,270  -->  00:05:10,093
Oh, sorry I'll run code.py so it's the same as before.
107

107

00:05:11,040  -->  00:05:15,510
What you've got is that mymodule and main
108

108

00:05:15,510  -->  00:05:17,750
are at the top level.
109

109

00:05:17,750  -->  00:05:19,580
When you're trying to do a relative import,
110

110

00:05:19,580  -->  00:05:22,320
what Python's going to do is it's going to remove the file
111

111

00:05:22,320  -->  00:05:23,870
and it's just going to try to append
112

112

00:05:23,870  -->  00:05:27,670
whatever you import from into the rest of the import path.
113

113

00:05:27,670  -->  00:05:31,900
So if we go to mylib and then we do from .operations
114

114

00:05:31,900  -->  00:05:35,387
import operator, what that's gonna do is it's gonna say,
115

115

00:05:35,387  -->  00:05:40,120
"Okay, mylib, you are inside libs.mylib."
116

116

00:05:40,120  -->  00:05:43,140
So, because you're trying to do a relative import,
117

117

00:05:43,140  -->  00:05:45,140
we're going to remove the file
118

118

00:05:45,140  -->  00:05:48,090
and we're gonna try to put operations at the end
119

119

00:05:48,090  -->  00:05:49,070
and import from there.
120

120

00:05:49,070  -->  00:05:52,180
So here it'll work because it'll do libs.operations
121

121

00:05:52,180  -->  00:05:54,500
and then it'll import operator from that.
122

122

00:05:54,500  -->  00:05:57,130
So if I run code.py again,
123

123

00:05:57,130  -->  00:05:59,030
you can see that it all works fine.
124

124

00:05:59,030  -->  00:06:01,050
There's no errors whatsoever.
125

125

00:06:01,050  -->  00:06:05,880
However, if by any reason you want to run your mylib file,
126

126

00:06:05,880  -->  00:06:08,950
for example to debug it or run some code inside it,
127

127

00:06:08,950  -->  00:06:11,010
make sure it works or something like that,
128

128

00:06:11,010  -->  00:06:13,730
you won't be able to because, of course,
129

129

00:06:13,730  -->  00:06:16,540
this now becomes main, if you run it,
130

130

00:06:16,540  -->  00:06:19,440
and then you can't use relative imports from inside it.
131

131

00:06:19,440  -->  00:06:22,180
So, if you are going to use relative imports,
132

132

00:06:22,180  -->  00:06:25,700
you always have to run the same file at the top level,
133

133

00:06:25,700  -->  00:06:28,093
otherwise you may encounter some issues.
134

134

00:06:28,950  -->  00:06:30,203
Going into operator.py,
135

135

00:06:31,110  -->  00:06:35,660
you can actually do from ..mylib import star, let's say,
136

136

00:06:35,660  -->  00:06:36,900
and what this does in Python
137

137

00:06:36,900  -->  00:06:39,640
is it accesses the parent folder.
138

138

00:06:39,640  -->  00:06:43,800
So again if operator is inside libs.operations,
139

139

00:06:43,800  -->  00:06:47,120
dot dot is going to try to remove the operation
140

140

00:06:48,111  -->  00:06:50,120
and go direct to the previous one.
141

141

00:06:50,120  -->  00:06:54,130
So it'll try to do libs.mylib. That's what the dot dot means
142

142

00:06:54,130  -->  00:06:57,240
it just skips the parent folder and goes up to the next one.
143

143

00:06:57,240  -->  00:06:59,810
So, of course in order to do that,
144

144

00:06:59,810  -->  00:07:02,010
you need to be at least two levels deep.
145

145

00:07:02,010  -->  00:07:04,950
Otherwise if you try to do that for example from libs.mylib,
146

146

00:07:04,950  -->  00:07:07,760
you're going to try to skip libs and go to the previous one,
147

147

00:07:07,760  -->  00:07:10,700
but there is no previous one, so you'll find that error.
148

148

00:07:10,700  -->  00:07:12,180
So, again in order to do this,
149

149

00:07:12,180  -->  00:07:14,990
you need to do something like that,
150

150

00:07:14,990  -->  00:07:17,493
and that you can see works totally fine.
151

151

00:07:19,040  -->  00:07:22,920
Let's go back to why we didn't print anything else out
152

152

00:07:22,920  -->  00:07:25,010
when we ran this code because as you can see
153

153

00:07:25,010  -->  00:07:27,650
this output is exactly identical to the one we had before,
154

154

00:07:27,650  -->  00:07:30,000
so it seems that this did nothing.
155

155

00:07:30,000  -->  00:07:32,400
But really what's happened is Python has realised
156

156

00:07:32,400  -->  00:07:37,010
that libs.mylib had already been imported by mymodule
157

157

00:07:37,010  -->  00:07:39,520
before we imported operator.
158

158

00:07:39,520  -->  00:07:41,560
So, it didn't try to import it again.
159

159

00:07:41,560  -->  00:07:45,490
This just reuses the import that's already on six modules.
160

160

00:07:45,490  -->  00:07:47,360
So that's why we didn't see any more output.
161

161

00:07:47,360  -->  00:07:50,480
mylib.py didn't run again when we tried to import this.
162

162

00:07:50,480  -->  00:07:53,020
It was already in dot modules.
163

163

00:07:53,020  -->  00:07:55,190
I also wanted to say that at any point in time
164

164

00:07:55,190  -->  00:07:58,820
if you wanted to import say operator.py from mymodule,
165

165

00:07:58,820  -->  00:08:01,123
you can do import libs.operations.operator,
166

166

00:08:02,160  -->  00:08:06,450
or of course, from libs.operations import operator.
167

167

00:08:06,450  -->  00:08:08,400
You can do that as well.
168

168

00:08:08,400  -->  00:08:10,620
By the way, this just means import everything
169

169

00:08:10,620  -->  00:08:13,270
that is inside this path here.
170

170

00:08:13,270  -->  00:08:15,300
So if there were multiple functions,
171

171

00:08:15,300  -->  00:08:16,470
you would import them all.
172

172

00:08:16,470  -->  00:08:18,720
If there's multiple variables defined in there,
173

173

00:08:18,720  -->  00:08:21,320
you would also import them, and so on.
174

174

00:08:21,320  -->  00:08:22,860
All right that's everything for this video.
175

175

00:08:22,860  -->  00:08:25,470
Thank you for joining me. I know this stuff is confusing,
176

176

00:08:25,470  -->  00:08:29,410
but my advice is to not use relative imports in Python.
177

177

00:08:29,410  -->  00:08:32,260
They are difficult to understand, they're confusing,
178

178

00:08:32,260  -->  00:08:35,220
they only work if you always run the same files,
179

179

00:08:35,220  -->  00:08:37,950
and they won't work if you try to run other files
180

180

00:08:37,950  -->  00:08:39,830
such as the ones that use relative imports
181

181

00:08:39,830  -->  00:08:42,290
for debugging or to try things out.
182

182

00:08:42,290  -->  00:08:45,100
So, don't use them. Use absolute imports instead.
183

183

00:08:45,100  -->  00:08:47,850
Your life will be much easier, and really,
184

184

00:08:47,850  -->  00:08:50,030
you're not gonna encounter any problems with that.
185

185

00:08:50,030  -->  00:08:52,930
So thanks for joining me and I'll see you in the next one.
