1
00:00:00,790 --> 00:00:02,200
Hi guys and welcome back!

2
00:00:02,200 --> 00:00:03,490
In this video we're going to learn

3
00:00:03,490 --> 00:00:06,990
about unpacking keyword arguments.

4
00:00:06,990 --> 00:00:08,920
Last video was a little bit confusing.

5
00:00:08,920 --> 00:00:11,700
Now it's going to get a little bit more confusing

6
00:00:11,700 --> 00:00:14,170
as we learn about keyword arguments.

7
00:00:14,170 --> 00:00:15,930
Once these two videos are over though

8
00:00:15,930 --> 00:00:19,361
you're going to have all of the tools necessary in Python

9
00:00:19,361 --> 00:00:22,640
to create any type of function,

10
00:00:22,640 --> 00:00:24,770
and use it in many different ways.

11
00:00:24,770 --> 00:00:26,860
So, up to now we've been learning about

12
00:00:26,860 --> 00:00:28,280
all these fundamental building blocks

13
00:00:28,280 --> 00:00:30,290
and this is one of the last ones.

14
00:00:30,290 --> 00:00:32,750
After this we can learn about object oriented programming

15
00:00:32,750 --> 00:00:35,290
and that's another type of beast altogether now.

16
00:00:35,290 --> 00:00:38,670
Let's start by defining a simple function

17
00:00:38,670 --> 00:00:41,900
that will use this unpacking of keyword arguments.

18
00:00:41,900 --> 00:00:45,685
So I'm gonna do star star, kwargs, now,

19
00:00:45,685 --> 00:00:50,594
args and kwargs, when you use star args and star star kwargs

20
00:00:50,594 --> 00:00:53,200
are the usual names for these things,

21
00:00:53,200 --> 00:00:54,370
but they don't have to be.

22
00:00:54,370 --> 00:00:56,690
You can use whatever variable name you want here

23
00:00:56,690 --> 00:00:59,580
and indeed with star args as well.

24
00:00:59,580 --> 00:01:01,140
We're going to just print them out,

25
00:01:01,140 --> 00:01:03,990
so I want you to take a look at what happens

26
00:01:03,990 --> 00:01:06,880
when I call my named function, and I say something like

27
00:01:06,880 --> 00:01:11,090
name equal Bob and age equal 25.

28
00:01:11,090 --> 00:01:12,800
If I run this code here,

29
00:01:12,800 --> 00:01:16,430
you can see that what we get out is a dictionary.

30
00:01:16,430 --> 00:01:19,100
So, we called our named function

31
00:01:19,100 --> 00:01:21,677
that does this dictionary unpacking

32
00:01:21,677 --> 00:01:26,150
with two keyword arguments, and what happens in Python

33
00:01:26,150 --> 00:01:29,430
is that these keyword arguments all get collected

34
00:01:29,430 --> 00:01:32,700
into this kwargs variable.

35
00:01:32,700 --> 00:01:34,280
That is what the star star does,

36
00:01:34,280 --> 00:01:37,020
it collects keyword arguments.

37
00:01:37,020 --> 00:01:39,400
So, all of these keyword arguments get collected

38
00:01:39,400 --> 00:01:42,810
and put into a dictionary where the dictionary key

39
00:01:42,810 --> 00:01:45,600
is equal ti the name of the keyword argument.

40
00:01:45,600 --> 00:01:49,110
So you end up with a name key and a Bob value

41
00:01:49,110 --> 00:01:53,743
for this one, and an age key and a 25 value for this one.

42
00:01:54,600 --> 00:01:59,290
The same way that you can collect named arguments

43
00:01:59,290 --> 00:02:01,550
into a dictionary you can go the other way round,

44
00:02:01,550 --> 00:02:04,800
you can unpack a dictionary into named arguments.

45
00:02:04,800 --> 00:02:07,710
So I'm going to make a small change to my named function.

46
00:02:07,710 --> 00:02:08,900
I'm going to pass in name

47
00:02:08,900 --> 00:02:11,600
and age and I'm going to print them out, name and age.

48
00:02:12,680 --> 00:02:15,380
And now I'm going to define a details dictionary

49
00:02:15,380 --> 00:02:20,060
which has a name of Bob, and an age of 25.

50
00:02:20,060 --> 00:02:23,570
Now I'm going to call my named function with my details.

51
00:02:23,570 --> 00:02:27,780
We know that this won't work because details is a dictionary

52
00:02:27,780 --> 00:02:30,560
and I'm passing it as a positional argument

53
00:02:30,560 --> 00:02:32,890
which means that the details dictionary

54
00:02:32,890 --> 00:02:35,600
will become a value for the name parameter.

55
00:02:35,600 --> 00:02:37,930
But the age parameter will not have a value.

56
00:02:37,930 --> 00:02:41,190
We need to pass that in separately, something like this.

57
00:02:41,190 --> 00:02:42,800
But of course that's not what we want to do.

58
00:02:42,800 --> 00:02:46,130
We don't want to pass in this whole thing as a name.

59
00:02:46,130 --> 00:02:48,000
That would be a bit weird, and if you run this

60
00:02:48,000 --> 00:02:50,710
you'll see that you get the entire dictionary printed out

61
00:02:50,710 --> 00:02:53,790
because that's the name variable, and then 25 printed out

62
00:02:53,790 --> 00:02:55,610
because that's the age variable.

63
00:02:55,610 --> 00:02:58,350
Instead what we want to do is we want to pass in

64
00:02:58,350 --> 00:03:03,350
the name key as the name parameter, and the age key

65
00:03:03,820 --> 00:03:06,010
as the age parameter, and we saw how to do this

66
00:03:06,010 --> 00:03:09,930
in the last video, just by unpacking the dictionary

67
00:03:09,930 --> 00:03:14,030
into two named arguments like that.

68
00:03:14,030 --> 00:03:18,450
When you do that, it treats the key as the name

69
00:03:18,450 --> 00:03:21,870
for the argument, and age as the key for the argument

70
00:03:21,870 --> 00:03:24,440
and assigns to them the value associated with those.

71
00:03:24,440 --> 00:03:28,620
So you do end up now with Bob and 25.

72
00:03:28,620 --> 00:03:31,740
Note that if you had star star kwargs

73
00:03:31,740 --> 00:03:35,033
which is the collection of multiple named arguments,

74
00:03:36,060 --> 00:03:38,820
you can print them out and you can still do this.

75
00:03:38,820 --> 00:03:41,330
What'll happen now is instead of doing

76
00:03:41,330 --> 00:03:45,960
name equal Bob and age equal 25,

77
00:03:45,960 --> 00:03:47,240
you're doing exactly the same thing

78
00:03:47,240 --> 00:03:50,550
but using this dictionary to pass in multiple

79
00:03:50,550 --> 00:03:53,510
keyword arguments and then they are being collected

80
00:03:53,510 --> 00:03:54,940
into this dictionary up here,

81
00:03:54,940 --> 00:03:56,710
and then you're gonna print a dictionary out.

82
00:03:56,710 --> 00:03:59,200
So that is how these two stars work.

83
00:03:59,200 --> 00:04:02,120
They can be used in a function to collect named arguments

84
00:04:02,120 --> 00:04:05,320
into a dictionary, or they can be used in a function call

85
00:04:05,320 --> 00:04:08,743
to unpack a dictionary into keyword arguments.

86
00:04:10,240 --> 00:04:13,140
Let's say we have another function called print nicely

87
00:04:13,140 --> 00:04:17,720
that is going to print out his dictionary into a nice format

88
00:04:17,720 --> 00:04:22,240
so, let's call the named function first

89
00:04:22,240 --> 00:04:23,530
to print the arguments out,

90
00:04:23,530 --> 00:04:25,830
and then we are going to print them nicely.

91
00:04:25,830 --> 00:04:30,610
So we're gonna do for arg, and value, in kwargs dot items.

92
00:04:30,610 --> 00:04:34,760
Then we're gonna print arg and the value.

93
00:04:34,760 --> 00:04:37,270
Notice that kwargs is a dictionary

94
00:04:37,270 --> 00:04:39,850
so you can use the items method on it

95
00:04:39,850 --> 00:04:42,660
so that you can iterate over two of these things.

96
00:04:42,660 --> 00:04:45,200
Notice that here we're using a whole bunch of things

97
00:04:45,200 --> 00:04:46,410
that we've learned so far,

98
00:04:46,410 --> 00:04:49,660
including normal data types like dictionaries.

99
00:04:49,660 --> 00:04:53,323
We are calling functions, we are de-structuring the tuple

100
00:04:53,323 --> 00:04:55,510
that that returns into two values.

101
00:04:55,510 --> 00:04:59,490
We are even unpacking and repacking named arguments.

102
00:04:59,490 --> 00:05:01,030
So there's a lot of stuff going on here

103
00:05:01,030 --> 00:05:03,390
and I know it's a little bit confusing.

104
00:05:03,390 --> 00:05:05,440
Now with this function we can do print nicely

105
00:05:05,440 --> 00:05:09,040
and we can pass name is Bob and age is 25

106
00:05:09,040 --> 00:05:12,360
and what's gonna happen is we're going to collect

107
00:05:12,360 --> 00:05:15,920
these named arguments into this dictionary.

108
00:05:15,920 --> 00:05:18,290
Then we're gonna call the named function,

109
00:05:18,290 --> 00:05:20,290
but we're going to unpack that dictionary

110
00:05:20,290 --> 00:05:22,040
into named arguments so we're gonna pass in

111
00:05:22,040 --> 00:05:24,440
name equal Bob and age equal 25.

112
00:05:24,440 --> 00:05:28,020
Those are then gonna be collected into this dictionary,

113
00:05:28,020 --> 00:05:29,080
and they're gonna be printed out,

114
00:05:29,080 --> 00:05:30,747
so we're gonna print a dictionary.

115
00:05:30,747 --> 00:05:32,680
And then we're gonna come back out here

116
00:05:32,680 --> 00:05:34,630
and we're going to iterate over the items,

117
00:05:34,630 --> 00:05:38,060
getting arg and value for each item in the dictionary

118
00:05:38,060 --> 00:05:41,650
which is gonna give us name and Bob and then age and 25.

119
00:05:41,650 --> 00:05:43,360
And finally we're going to print those out

120
00:05:43,360 --> 00:05:44,650
in a bit of a nicer way.

121
00:05:44,650 --> 00:05:46,170
So we're gonna print the dictionary first,

122
00:05:46,170 --> 00:05:47,623
and then two more lines.

123
00:05:48,500 --> 00:05:50,713
And that is indeed what we get back.

124
00:05:53,070 --> 00:05:54,700
You can use both actually,

125
00:05:54,700 --> 00:05:58,740
star args and star star kwargs if you want.

126
00:05:58,740 --> 00:06:00,920
And nothing changes, you're gonna collect

127
00:06:00,920 --> 00:06:03,340
all the positional arguments into args

128
00:06:03,340 --> 00:06:06,100
and all the named arguments into kwargs.

129
00:06:06,100 --> 00:06:08,120
So you can do something like both.

130
00:06:08,120 --> 00:06:12,330
One, three, five, name equal Bob, and age equal 25.

131
00:06:12,330 --> 00:06:14,740
One, three and five will be collected into args

132
00:06:14,740 --> 00:06:16,560
because they are positional arguments.

133
00:06:16,560 --> 00:06:18,330
Name equal Bob and age equal 25

134
00:06:18,330 --> 00:06:20,480
will be collected into kwargs.

135
00:06:20,480 --> 00:06:22,403
So if we run that, you can see that you get

136
00:06:22,403 --> 00:06:26,073
a tuple of arguments, and then a dictionary of arguments.

137
00:06:27,250 --> 00:06:30,350
This syntax here, args and kwargs with the stars

138
00:06:30,350 --> 00:06:35,350
is normally used to accept an unlimited number of arguments.

139
00:06:35,960 --> 00:06:38,080
So you can pass in anything you want to this function,

140
00:06:38,080 --> 00:06:40,860
any positional arguments and any named arguments

141
00:06:40,860 --> 00:06:44,740
and it will accept them, and that is normally used

142
00:06:44,740 --> 00:06:47,300
so that some of those arguments or all of those arguments

143
00:06:47,300 --> 00:06:49,780
can be passed onto another function.

144
00:06:49,780 --> 00:06:54,610
Here's an example of something that is done quite frequently

145
00:06:54,610 --> 00:06:56,340
and we haven't written this code,

146
00:06:56,340 --> 00:06:58,860
don't worry about how it's implemented.

147
00:06:58,860 --> 00:07:02,910
But you have a post function that takes in

148
00:07:02,910 --> 00:07:06,830
a URL, some data, some variable called json,

149
00:07:06,830 --> 00:07:10,040
and then any number of keyword arguments.

150
00:07:10,040 --> 00:07:13,420
And it returns just calling another function.

151
00:07:13,420 --> 00:07:17,200
And it passes the URL, the data, the json,

152
00:07:17,200 --> 00:07:19,350
and all of the keyword arguments.

153
00:07:19,350 --> 00:07:22,150
So it essentially seems to do the same thing,

154
00:07:22,150 --> 00:07:25,920
but it also adds an extra argument.

155
00:07:25,920 --> 00:07:28,830
So this is very common pattern to do in Python.

156
00:07:28,830 --> 00:07:32,480
To have a function that seemingly just calls another

157
00:07:32,480 --> 00:07:34,910
but adds something more to it.

158
00:07:34,910 --> 00:07:38,170
And that is used to simplify calling this initial function

159
00:07:38,170 --> 00:07:41,890
so that you don't have to pass in this argument as well.

160
00:07:41,890 --> 00:07:44,850
So just an example of the kwargs being used

161
00:07:44,850 --> 00:07:48,380
to essentially pass arguments from one function to another

162
00:07:48,380 --> 00:07:51,653
until they get used, so that's very common thing to do.

163
00:07:52,850 --> 00:07:55,010
A final example, if you define a function

164
00:07:55,010 --> 00:08:00,010
that used this unpacking, you need to call it with a mapping

165
00:08:00,480 --> 00:08:03,120
if you're going to pass in this star star.

166
00:08:03,120 --> 00:08:05,860
So if you do star star Bob, you're gonna get an error

167
00:08:05,860 --> 00:08:07,230
because this is not a dictionary.

168
00:08:07,230 --> 00:08:09,940
Similarly with star star none, you're going to get an error

169
00:08:09,940 --> 00:08:11,590
because that's not a dictionary.

170
00:08:11,590 --> 00:08:14,080
So if you're working with variables in your code

171
00:08:14,080 --> 00:08:16,580
and then eventually you're passing them unpacked

172
00:08:16,580 --> 00:08:18,990
to a function then you must make sure

173
00:08:18,990 --> 00:08:20,280
that they are dictionaries.

174
00:08:20,280 --> 00:08:22,680
If they are anything else then you're gonna get an error

175
00:08:22,680 --> 00:08:25,130
when this line runs, som that's something that you'll see

176
00:08:25,130 --> 00:08:27,040
quite frequently in Python code.

177
00:08:27,040 --> 00:08:30,140
The variable has an unexpected value or something like that

178
00:08:30,140 --> 00:08:32,370
and students sometimes struggle to determine

179
00:08:32,370 --> 00:08:34,260
why you get an error.

180
00:08:34,260 --> 00:08:36,660
That's because sometimes the variables that we use

181
00:08:36,660 --> 00:08:39,260
may not be what we expect.

182
00:08:39,260 --> 00:08:41,800
That's it for this video, thanks for joining me in this one.

183
00:08:41,800 --> 00:08:44,700
I hope we've enjoyed it, and I'll see you in the next one.

