1
00:00:05,880 --> 00:00:11,630
Welcome to this lecture on decorator's we're not going to discuss a more advanced Python topic which

2
00:00:11,630 --> 00:00:15,950
is known as a decorator and a decorator allows you to decorate a function.

3
00:00:15,950 --> 00:00:19,710
So this is just what that word decorate actually means in this context.

4
00:00:20,650 --> 00:00:22,990
Imagine you just created a function in Python.

5
00:00:23,110 --> 00:00:28,040
You have the simple function and it does some stuff and then return something.

6
00:00:28,040 --> 00:00:33,050
Now imagine that you wanted to add some new capabilities to the function you wanted to keep the original

7
00:00:33,050 --> 00:00:38,450
simple stuff but now you want to add more abilities by doing some more things and then returning something

8
00:00:38,450 --> 00:00:40,430
else.

9
00:00:40,520 --> 00:00:41,860
So I have two options.

10
00:00:41,960 --> 00:00:47,530
You could just add that extra code that extra functionality to your old function just like we did here.

11
00:00:47,540 --> 00:00:50,140
It took that same function and then added some more stuff to it.

12
00:00:51,010 --> 00:00:57,630
Or you could create a brand new function that contains the old code and then add the new code to that.

13
00:00:57,710 --> 00:01:00,370
But what if you then want to remove that extra functionality.

14
00:01:00,500 --> 00:01:05,360
So neither of these solutions is actually pretty good because then you'd either have to use the old

15
00:01:05,360 --> 00:01:09,070
function or delete the new code manually.

16
00:01:09,080 --> 00:01:11,300
So is there a better way.

17
00:01:11,360 --> 00:01:15,890
Maybe if we can have some sort of quick on off switch to quickly add this functionality or remove it

18
00:01:16,400 --> 00:01:18,580
at our leisure.

19
00:01:18,740 --> 00:01:24,950
So Python has decorator's that apply to tack on this extra functionality to an already existing function

20
00:01:25,340 --> 00:01:32,170
and they're going to use the at operator and are then placed on top of the original function snake actually

21
00:01:32,200 --> 00:01:35,330
easily add on extra functionality with a decorator.

22
00:01:35,530 --> 00:01:41,290
So here we have our original simple function and then we can decorate with some decorator to add in

23
00:01:41,530 --> 00:01:45,690
that extra functionality to the function.

24
00:01:45,700 --> 00:01:49,200
So this idea is actually pretty abstract in practice of Python syntax.

25
00:01:49,360 --> 00:01:53,620
So what we're going to do is we're going to go through the steps of manually building a decorator ourselves

26
00:01:53,920 --> 00:01:57,090
to show what the operator is actually doing behind the scenes.

27
00:01:57,280 --> 00:02:01,540
Again when we're actually using the operator and decorators with flask we're pretty much just going

28
00:02:01,540 --> 00:02:05,070
to tack on the operator and it's just going to be a single line.

29
00:02:05,140 --> 00:02:09,340
But to really understand what's happening behind the scenes in this lecture we're going to build out

30
00:02:09,520 --> 00:02:12,480
that decorator process completely manually.

31
00:02:12,490 --> 00:02:17,460
OK let's begin by thinking about functions within other functions.

32
00:02:17,500 --> 00:02:22,260
So remember I could have a very simple function such as a function called Hello.

33
00:02:22,540 --> 00:02:29,950
And all this function does is it just prints out Hello.

34
00:02:30,040 --> 00:02:38,370
So if I save that and I actually run it at the bottom here and I run this file I get back up one line.

35
00:02:38,370 --> 00:02:39,880
Let me expand this a little bit.

36
00:02:39,930 --> 00:02:40,580
I get back.

37
00:02:40,710 --> 00:02:41,500
Hello.

38
00:02:41,910 --> 00:02:42,400
OK.

39
00:02:42,600 --> 00:02:43,610
So now let's have hello.

40
00:02:43,620 --> 00:02:46,940
Accept a parameter such as a name.

41
00:02:46,980 --> 00:02:54,330
So by default the name will be Jose and instead of printing Hello we're just going to say the hello

42
00:02:54,330 --> 00:02:57,880
function has been run

43
00:03:00,740 --> 00:03:05,720
and then we're going to find a function inside of the hello function and it does seem strange to you.

44
00:03:05,720 --> 00:03:08,700
Go ahead and review the scope lecture from earlier.

45
00:03:08,950 --> 00:03:11,340
But I'm going to have another function here called greet.

46
00:03:11,900 --> 00:03:20,070
And in this function instead of printing something I'm going to be returning and I'll say space is here.

47
00:03:20,330 --> 00:03:21,920
This is inside

48
00:03:28,140 --> 00:03:34,470
and then what I'm going to do here is I'm going to print the result of calling greet.

49
00:03:34,560 --> 00:03:40,260
So that means when I call hello and execute that function I'm going to print out the hello function

50
00:03:40,260 --> 00:03:46,560
that's been run then I'll define discrete function and then I'll actually call and print that function.

51
00:03:46,620 --> 00:03:47,720
So let's check it out.

52
00:03:48,240 --> 00:03:50,280
Let's run hello and see what happens.

53
00:03:51,520 --> 00:03:56,520
So here I'm getting the hello function has been run and then this is inside the grid.

54
00:03:56,650 --> 00:04:00,400
So to you if you want to have this extra spacing I kind of like spacing because it's enough.

55
00:04:00,430 --> 00:04:03,020
It's a good way to visualize that great insight.

56
00:04:03,030 --> 00:04:03,870
Hello.

57
00:04:04,200 --> 00:04:07,210
And in fact let's do this one more time.

58
00:04:08,580 --> 00:04:13,890
We're going to say create a welcome function that's going to return.

59
00:04:13,890 --> 00:04:27,820
This is inside let's say this insight welcome save that and then I'll call greets and also call welcome.

60
00:04:27,840 --> 00:04:31,680
So now when I run this I get back to the function has been run.

61
00:04:31,740 --> 00:04:32,650
This is inside.

62
00:04:32,730 --> 00:04:33,960
This is inside a welcome.

63
00:04:34,080 --> 00:04:39,680
So I'm both calling Hello function defining greeting welcome functions and then executing those greet

64
00:04:39,680 --> 00:04:41,000
and welcome functions.

65
00:04:41,020 --> 00:04:44,310
Notice all of this Lines 2 through 11.

66
00:04:44,310 --> 00:04:47,110
Those are all happening within the helo function itself.

67
00:04:47,180 --> 00:04:49,860
So zoom out a little bit so we can see the whole picture.

68
00:04:49,860 --> 00:04:54,210
But again all of this codes inside this one helo function.

69
00:04:54,210 --> 00:04:57,320
Now let's talk about actually returning a function.

70
00:04:57,330 --> 00:04:59,370
This is something we haven't seen before.

71
00:04:59,370 --> 00:05:04,260
So we've briefly seen already functions within other functions that we haven't actually seen the idea

72
00:05:04,320 --> 00:05:06,330
of returning a function.

73
00:05:06,330 --> 00:05:07,770
So I'm going to do the following.

74
00:05:09,640 --> 00:05:18,330
I'll see if the name provided is equal to Jose then return grete

75
00:05:21,090 --> 00:05:22,150
else.

76
00:05:23,610 --> 00:05:26,500
Return welcome.

77
00:05:26,510 --> 00:05:29,300
OK so let's think of what's actually going to happen here.

78
00:05:30,970 --> 00:05:34,810
I have this halo function and it takes an unnamed parameter.

79
00:05:34,810 --> 00:05:42,130
It just goes ahead and prints Hey hello function has been run then it's going to find the function to

80
00:05:42,130 --> 00:05:48,380
find the welcome function and then if the name is equal to Jose it's actually going to return the Greek

81
00:05:48,400 --> 00:05:49,240
function itself.

82
00:05:49,240 --> 00:05:50,890
Notice it's not executing it.

83
00:05:50,890 --> 00:05:54,720
It's actually returning this entire function for you to then play around with.

84
00:05:54,820 --> 00:05:59,810
Otherwise if the name is not easy it's going to return the entirety of the welcome function.

85
00:05:59,830 --> 00:06:00,980
So let's see what happens.

86
00:06:00,990 --> 00:06:12,980
I'm going to set X equal to hello and then I'm going to say execute x.

87
00:06:13,020 --> 00:06:19,920
So when I run this knows what happens I get back the hello function has been run and then I'm going

88
00:06:19,920 --> 00:06:23,030
to print the result of executing X..

89
00:06:23,040 --> 00:06:25,860
You can clearly see this.

90
00:06:25,960 --> 00:06:27,660
So I get back to hello functions and run.

91
00:06:27,670 --> 00:06:29,430
And then this is inside green.

92
00:06:29,650 --> 00:06:31,450
So what's actually happening here.

93
00:06:31,450 --> 00:06:33,850
Well the name by default is Jose.

94
00:06:34,150 --> 00:06:36,430
So then we print out the hello function to run.

95
00:06:36,430 --> 00:06:40,020
So we just executed line 15 the hello functionals and run.

96
00:06:40,180 --> 00:06:41,920
Then we define the function.

97
00:06:41,970 --> 00:06:45,180
We find the welcome function and as the name was he called Jose.

98
00:06:45,400 --> 00:06:51,180
I'm going to return the function then upon returning the function I set that equal to x.

99
00:06:51,220 --> 00:06:54,600
So this line right here x is equal to Hello.

100
00:06:54,640 --> 00:06:57,160
This is basically saying x is equal to

101
00:07:00,610 --> 00:07:05,970
because I'm returning great here and because I'm not executing it that means I can later actually execute

102
00:07:06,070 --> 00:07:09,220
X and print out the result which is going to return.

103
00:07:09,220 --> 00:07:11,080
This is inside the Greek.

104
00:07:11,320 --> 00:07:16,290
So this is an idea that we're going to be able to use to actually manually build out decorator's.

105
00:07:16,300 --> 00:07:19,610
So again this idea is called returning a function.

106
00:07:19,610 --> 00:07:24,170
I am just going to literally return a function by calling another function.

107
00:07:24,190 --> 00:07:25,280
So let's try this again.

108
00:07:25,300 --> 00:07:31,740
I'm not going to set my name equal to let's say Sammy say that and let's run it.

109
00:07:32,800 --> 00:07:35,580
And now I see the halo function has been run.

110
00:07:35,850 --> 00:07:37,860
This is inside welcome.

111
00:07:37,870 --> 00:07:40,510
So why is it saying this is inside welcome.

112
00:07:40,510 --> 00:07:43,580
Because my name provided is no longer equal to Jose.

113
00:07:43,640 --> 00:07:46,980
So then this else executes and it returns the welcome function.

114
00:07:46,990 --> 00:07:51,000
Again it doesn't execute the welcome function only returns the welcome function.

115
00:07:51,010 --> 00:07:56,890
It's only when actually execute X here and print out the result that I get to see this is in sidewalk.

116
00:07:57,190 --> 00:07:59,620
So this is known as returning a function.

117
00:07:59,620 --> 00:08:02,590
Now we can also use functions as arguments.

118
00:08:02,590 --> 00:08:06,820
This is the other main idea we need to understand for creating our own decorator's.

119
00:08:06,820 --> 00:08:12,040
So so far we've reviewed functions inside functions returning functions and the final thing we need

120
00:08:12,040 --> 00:08:18,760
to talk about is functions as arguments are going to create a function called hello and this one is

121
00:08:18,760 --> 00:08:20,980
just going to return.

122
00:08:20,980 --> 00:08:22,400
Hi Jose.

123
00:08:23,080 --> 00:08:32,680
I'll create another function called other and it takes in a parameter func and it's going to print some

124
00:08:33,850 --> 00:08:34,720
other code.

125
00:08:36,930 --> 00:08:40,940
And then we'll print out phunk but knows what I'm going to do here.

126
00:08:40,950 --> 00:08:49,740
I'm actually going to execute phunk so I'm going to assume that func flips assume that the func passed

127
00:08:49,740 --> 00:08:56,160
in is a function.

128
00:08:56,180 --> 00:09:01,190
So again I'm taking this as a parameter instead of my function and then I'm actually going to execute

129
00:09:01,190 --> 00:09:02,540
it.

130
00:09:02,580 --> 00:09:07,150
So let's say that and see what happens when I say other passen.

131
00:09:07,170 --> 00:09:11,330
Hello I'm going to run this again and I see.

132
00:09:11,520 --> 00:09:14,270
Hi Jose and some other code.

133
00:09:14,370 --> 00:09:18,220
So what's actually happening here is I've defined this function.

134
00:09:18,400 --> 00:09:19,740
Hello which returns.

135
00:09:19,740 --> 00:09:20,780
Hi Jose.

136
00:09:21,060 --> 00:09:26,910
And then I'm passing in that function notice here I'm not calling it I'm just passing it in and then

137
00:09:26,910 --> 00:09:28,970
this other function is going to take it in.

138
00:09:29,040 --> 00:09:33,270
It's going to print some other code and it's going to grab the function that was passed in this case.

139
00:09:33,270 --> 00:09:33,950
Hello.

140
00:09:34,100 --> 00:09:35,220
Execute it to return.

141
00:09:35,220 --> 00:09:36,040
Hi Jose.

142
00:09:36,210 --> 00:09:37,680
And then print out that result.

143
00:09:37,800 --> 00:09:40,600
Which is why when I run this I see some other code.

144
00:09:40,890 --> 00:09:42,270
Line 5 and then.

145
00:09:42,270 --> 00:09:43,240
Hi Jose.

146
00:09:43,350 --> 00:09:49,140
Which is the product of line 7 which is passing in the hello function executing it and returning Hi

147
00:09:49,140 --> 00:09:50,950
Jose to be printed out.

148
00:09:51,330 --> 00:09:55,150
So this is known as passing in a function as an argument.

149
00:09:55,170 --> 00:10:00,210
Now that we understand these three fundamental ideas of functions within functions returning functions

150
00:10:00,450 --> 00:10:05,670
and using function as arguments we can now actually build and create our own decorator.

151
00:10:05,670 --> 00:10:06,720
So let's try this out.

152
00:10:08,580 --> 00:10:19,560
I'm going to create a function called new underscore decorator and it takes an some phunk than inside

153
00:10:19,560 --> 00:10:20,190
of it.

154
00:10:20,190 --> 00:10:29,380
I'm going to create what I would call wrap func a wrapping function and it's going to print some code

155
00:10:30,650 --> 00:10:37,700
before executing phunk then I'm actually going to execute phunk.

156
00:10:37,730 --> 00:10:40,260
So remember this is the phunk that's passed in here.

157
00:10:40,460 --> 00:10:46,580
So that has to do with the global scope I'm going to be able to call it and then I'm going to print

158
00:10:48,110 --> 00:11:00,540
code here after executing phunk And then when I'm going to do is my new decorator function is going

159
00:11:00,540 --> 00:11:07,480
to return rap funk Sozzi and try to understand the idea of what's happening here.

160
00:11:07,700 --> 00:11:15,590
This function new decorator accepts a function then inside of the new decorator function I create a

161
00:11:15,590 --> 00:11:23,360
wrap function that can add some code before I call func execute func and then add some more code such

162
00:11:23,360 --> 00:11:30,080
as printing code here after executing func and then this new function which has effectively decorated.

163
00:11:30,080 --> 00:11:35,410
Or add more functionality to phunk is then going to be returned.

164
00:11:35,630 --> 00:11:39,110
And then finally I'm going to create a function that needs this declaration.

165
00:11:39,230 --> 00:11:52,890
So I'll say this func needs a decorator going to say just prints please decorate me.

166
00:11:52,920 --> 00:11:59,940
OK so let's see what happens when I say just call phunk needs a decorator by itself.

167
00:11:59,940 --> 00:12:05,970
So if I run this code and I get myself a little more room here it says please decorate me and that's

168
00:12:05,970 --> 00:12:06,600
it.

169
00:12:06,630 --> 00:12:08,770
Which makes sense because that's all it's being printed here.

170
00:12:08,800 --> 00:12:10,180
It says Please decorate me.

171
00:12:10,240 --> 00:12:12,830
I call Falconis decorator and that's it.

172
00:12:12,840 --> 00:12:15,280
Now let's try the following.

173
00:12:15,330 --> 00:12:23,630
I'm going to say phunk needs a decorator and I'm going to assign it to new decorator passing in phunk

174
00:12:23,660 --> 00:12:30,240
it needs decorator so what does this is doing is I'm taking what phunk needs a decorator currently is

175
00:12:30,300 --> 00:12:32,590
which is just printing out please decorate me.

176
00:12:32,970 --> 00:12:39,470
I'm taking this entire function right here and I'm passing into new decorator the new decorator is going

177
00:12:39,470 --> 00:12:44,410
to take the funk needs decorator and it's going to build it into wrap function.

178
00:12:44,430 --> 00:12:48,540
It's going to print some code before executing it then it's going to execute it and then it's going

179
00:12:48,540 --> 00:12:54,630
to print some code after it and it's going to return that new repped function and I'm re-assigning that

180
00:12:54,750 --> 00:12:56,640
to function means decorator.

181
00:12:56,640 --> 00:13:02,060
So now let's see what happens when I actually execute phunk needs decorator.

182
00:13:02,190 --> 00:13:07,740
I run this and if I expand this I can see the results and I'll get back some code before executing the

183
00:13:07,740 --> 00:13:08,680
function.

184
00:13:08,760 --> 00:13:12,660
Please decorate me and code here after executing phunk.

185
00:13:12,660 --> 00:13:20,190
So this is basically what a decorator does all the decorator does is it takes in the function that you

186
00:13:20,190 --> 00:13:22,260
want to decorate.

187
00:13:22,390 --> 00:13:28,780
It creates a new function out of it with some extra functionality either before or after it or both

188
00:13:29,350 --> 00:13:31,530
and then execute the function as well.

189
00:13:31,630 --> 00:13:35,660
And this new wrapped version of your function gets returned.

190
00:13:35,800 --> 00:13:42,310
Now instead of doing this sort of re-assignment which can be a little ugly and said well we can do is

191
00:13:42,310 --> 00:13:49,660
we can use the app notation to say new decorator and that performs the exact same thing that we just

192
00:13:49,660 --> 00:13:50,970
saw earlier.

193
00:13:50,980 --> 00:13:58,100
So that line performs essentially what line 16 is showing here.

194
00:13:58,240 --> 00:14:04,600
So Line 12 just tagging this function with that new decorator is the same as doing this right here.

195
00:14:04,870 --> 00:14:06,930
Except this is really easy to turn off anon.

196
00:14:06,970 --> 00:14:10,440
We can just commented out if we don't want it to be decorated or commented in.

197
00:14:10,480 --> 00:14:12,050
If we do want it to be decorated.

198
00:14:12,220 --> 00:14:18,160
Now we no longer need to add in this code manually or copy and paste this entire function and have kind

199
00:14:18,160 --> 00:14:19,900
of two versions of it instead.

200
00:14:19,930 --> 00:14:26,550
I can have this decorator function which I can easily then turn off or back on.

201
00:14:26,620 --> 00:14:27,210
OK.

202
00:14:27,430 --> 00:14:31,330
So let's see now that decorator in action I'm going to save this.

203
00:14:31,570 --> 00:14:32,870
Run this file again.

204
00:14:33,820 --> 00:14:39,290
And if we expand this to see the results I get back some code before in the function please decorate

205
00:14:39,290 --> 00:14:40,400
me code here.

206
00:14:40,400 --> 00:14:46,250
After executing function again let me just walk through everything here because this is basically it's

207
00:14:46,250 --> 00:14:50,280
all decorator is we have a function that needs decoration.

208
00:14:50,600 --> 00:14:56,510
And what we do is we decorate it with this at symbol new decorator and then that's going to be passed

209
00:14:56,600 --> 00:15:02,900
in to this new decorator function which is then going to construct inside of this entire new decorator

210
00:15:02,900 --> 00:15:03,620
function.

211
00:15:03,740 --> 00:15:05,950
It constructs this new wrapping function.

212
00:15:06,350 --> 00:15:08,110
You can execute some code.

213
00:15:08,570 --> 00:15:14,900
Call the function then execute some more code after it and you return this new like souped up or decorated

214
00:15:14,900 --> 00:15:17,040
version of your original function.

215
00:15:17,450 --> 00:15:23,150
And then if you ever want to actually wrap or decorate your function you just tag your original function

216
00:15:23,180 --> 00:15:24,340
with this symbol.

217
00:15:24,620 --> 00:15:28,180
And then the name of this decorator and that's it.

218
00:15:28,550 --> 00:15:30,950
OK I know this can be pretty complicated.

219
00:15:31,040 --> 00:15:34,850
And luckily we're never actually going to build manually our own decorators.

220
00:15:34,850 --> 00:15:39,590
Instead we'll be using the built in decorators that flask provides for us and we'll just be tagging

221
00:15:39,590 --> 00:15:41,820
them at and then decorator.

222
00:15:41,840 --> 00:15:45,590
So if you didn't understand this fully and wouldn't feel comfortable building out your own decorator's

223
00:15:46,070 --> 00:15:50,060
I would pretty much say don't really worry about it because you'll never have to actually do this when

224
00:15:50,060 --> 00:15:55,100
working with flask yourself instead you'll just be doing what we have here on line 12 adding a simple

225
00:15:55,160 --> 00:15:56,420
decorator line of code.

226
00:15:56,570 --> 00:16:00,900
But I do want to show you what's going on behind the scenes in case you are interested in it.

227
00:16:00,980 --> 00:16:02,600
All right that's it.

228
00:16:02,600 --> 00:16:03,630
We'll see you at the next lecture.
