1 00:00:00,240 --> 00:00:02,390 I'm pretty sure you could guess how this works. 2 00:00:02,390 --> 00:00:05,760 But let's talk a bit about how to make methods that take parameters 3 00:00:05,760 --> 00:00:07,320 other than self. 4 00:00:07,320 --> 00:00:10,330 Python doesn't like to surprise us and definitely doesn't here. 5 00:00:10,330 --> 00:00:11,930 Just like with standard functions, 6 00:00:11,930 --> 00:00:14,320 we can add any number of parameters to our methods. 7 00:00:14,320 --> 00:00:17,300 We can use args and kwargs too if we want. 8 00:00:17,300 --> 00:00:20,790 So, let's add a new method down here and let's call this hide. 9 00:00:22,550 --> 00:00:26,260 And let's take self, of course, an instance, and let's take a new argument 10 00:00:26,260 --> 00:00:29,350 which is light_level, right, because it's easier to hide in the dark, and 11 00:00:29,350 --> 00:00:33,576 we're going to return if self.sneak is equal to true, or sneaky rather, 12 00:00:33,576 --> 00:00:37,780 and that the light_level is less than ten. 13 00:00:39,080 --> 00:00:41,750 Okay? So, if the light_level's is less than ten, 14 00:00:41,750 --> 00:00:45,100 you can always hide so long as you're a sneaky thief. 15 00:00:45,100 --> 00:00:46,020 Sort of the rules of our game. 16 00:00:46,020 --> 00:00:50,172 All right, so let's go and try this again in our shell. 17 00:00:54,022 --> 00:00:56,481 And let's make Thief. 18 00:00:56,481 --> 00:01:01,044 All right, so now let's try kenneth.hide when the light level's (4). 19 00:01:02,610 --> 00:01:03,410 True. 20 00:01:03,410 --> 00:01:07,344 Cool, and that's expected because I am sneaky and 21 00:01:07,344 --> 00:01:10,190 the light_level is below ten, okay? 22 00:01:10,190 --> 00:01:13,620 Let's try kenneth.hide and the light_level is 14. 23 00:01:13,620 --> 00:01:16,349 And that one comes out as false, okay? 24 00:01:16,349 --> 00:01:21,211 And then, if we do kenneth.sneaky equals False, and kenneth.hide and 25 00:01:21,211 --> 00:01:23,650 it's pitch black at zero, False. 26 00:01:23,650 --> 00:01:24,400 So, cool. 27 00:01:24,400 --> 00:01:26,060 That's working just like I expected. 28 00:01:27,900 --> 00:01:31,530 Let's talk about a special method though and one that you'll likely use a lot. 29 00:01:31,530 --> 00:01:34,300 When you create a new instance of a class, Python looks for 30 00:01:34,300 --> 00:01:38,450 a method named double underscore init double underscore. 31 00:01:38,450 --> 00:01:42,350 The double underscores, or as I call them, dunders, on both sides, 32 00:01:42,350 --> 00:01:45,680 indicate that the method is the one that Python will run on its own and 33 00:01:45,680 --> 00:01:48,190 that we don't usually need to worry about. 34 00:01:48,190 --> 00:01:50,190 At least we don't have to use it explicitly, 35 00:01:50,190 --> 00:01:52,280 we don't have to call it ourselves. 36 00:01:52,280 --> 00:01:55,590 Now, this method lets us control how the classes are created or 37 00:01:55,590 --> 00:01:58,430 initialized, which is why it's called init. 38 00:01:58,430 --> 00:02:01,110 Let's make our Thief a little smarter in its creation. 39 00:02:01,110 --> 00:02:04,480 So, let's add def, init, and there's those double underscores. 40 00:02:04,480 --> 00:02:09,890 And this'll take self, it'll take a name, it'll take a sneaky argument. 41 00:02:09,890 --> 00:02:12,450 We'll automatically set to True, and 42 00:02:12,450 --> 00:02:16,330 it'll take any other kwargs that happen to come in, any other keyword arguments. 43 00:02:16,330 --> 00:02:22,490 So, we'll say self.name = name, and we'll say self.sneaky = sneaky. 44 00:02:22,490 --> 00:02:23,540 All right? And everything else, 45 00:02:23,540 --> 00:02:24,500 we're gonna leave alone. 46 00:02:24,500 --> 00:02:27,710 And we could actually make this a little easier here. 47 00:02:27,710 --> 00:02:34,370 We could say, instead of checking the self.sneaky, 48 00:02:34,370 --> 00:02:38,100 we could return self.sneaky and that one. 49 00:02:38,100 --> 00:02:43,810 So, that way our two methods are pretty similar to each other. 50 00:02:43,810 --> 00:02:44,540 Okay. 51 00:02:44,540 --> 00:02:46,620 So, we have a couple of new things in this one. 52 00:02:46,620 --> 00:02:48,160 Let's try it out. 53 00:02:48,160 --> 00:02:53,920 Okay, back into Python from characters import Thief, 54 00:02:55,500 --> 00:03:00,530 kenneth equals Thief, and we forgot to write a name, okay? 55 00:03:00,530 --> 00:03:01,950 So, let's add a name under this. 56 00:03:01,950 --> 00:03:05,550 So, I'm gonna add in Kenneth, and I'm gonna go ahead and say False for 57 00:03:05,550 --> 00:03:06,450 the sneaky part. 58 00:03:07,760 --> 00:03:08,410 Okay, cool. 59 00:03:08,410 --> 00:03:11,093 So now, let's do kenneth.name. 60 00:03:11,093 --> 00:03:13,520 That gives me back Kenneth, nice. 61 00:03:13,520 --> 00:03:16,690 And if we do kenneth.sneaky, we get back False. 62 00:03:16,690 --> 00:03:19,020 So, when I created the instance, I passed two arguments, 63 00:03:19,020 --> 00:03:22,430 which Python plopped into the two arguments in the init method. 64 00:03:22,430 --> 00:03:26,080 Then we assigned each of those to a different attribute on the instance, 65 00:03:26,080 --> 00:03:27,584 by using self, right? 66 00:03:27,584 --> 00:03:32,730 self.name = name, self.sneaky = sneaky, that's awesome, okay. 67 00:03:32,730 --> 00:03:34,720 So, what about this kwargs thing? 68 00:03:34,720 --> 00:03:39,120 Well if you remember, **kwargs is the dictionary full of key value pairs. 69 00:03:39,120 --> 00:03:42,906 Let's loop through that and assign all of those things to the instance. 70 00:03:46,928 --> 00:03:52,480 So, down here below that, let's do for key, value in kwargs.items(), 71 00:03:52,480 --> 00:03:58,306 and then we'll use a new method, or a new function rather called setattr, 72 00:03:58,306 --> 00:04:01,821 and let's specify the instance to set it on, 73 00:04:01,821 --> 00:04:06,860 we attribute the set and the value to get to that attribute. 74 00:04:06,860 --> 00:04:11,532 So, the setattr function is amazingly useful in situations like this because we 75 00:04:11,532 --> 00:04:16,028 don't know the name of the attributes that we need to create. 76 00:04:16,028 --> 00:04:22,870 So, said do that with this random values that come in this user's supplied values. 77 00:04:22,870 --> 00:04:26,580 There is a sneakier way of doing this but is less clear. 78 00:04:26,580 --> 00:04:28,090 So, I tend to avoid it. 79 00:04:28,090 --> 00:04:30,500 I’ve put it in the teacher's notes though if you’re curious. 80 00:04:30,500 --> 00:04:32,610 But, for now let’s try this out. 81 00:04:35,080 --> 00:04:36,200 Pull our console back up. 82 00:04:37,710 --> 00:04:38,240 Python. 83 00:04:39,490 --> 00:04:41,150 From characters, import Thief. 84 00:04:43,060 --> 00:04:44,650 kenneth = Thief(). 85 00:04:44,650 --> 00:04:46,490 I keep forgetting to supply that name. 86 00:04:47,570 --> 00:04:50,135 So, we'll do Kenneth, we'll leave sneaky alone. 87 00:04:50,135 --> 00:04:54,110 We'll say scars=None, and 88 00:04:54,110 --> 00:04:59,357 favorite_weapon="Wit", cool. 89 00:04:59,357 --> 00:05:03,041 So, if I do kenneth.name, we get back Kenneth, If I do kenneth.sneaky, 90 00:05:03,041 --> 00:05:06,635 I should get True, because that's what we set as the default. 91 00:05:06,635 --> 00:05:11,255 And if I do kenneth.favorite_weapon, I get Wit, cool. 92 00:05:11,255 --> 00:05:16,250 So, it looks like that works and that lets us add extra information to our instances. 93 00:05:16,250 --> 00:05:19,000 You're doing great with building simple custom classes and 94 00:05:19,000 --> 00:05:20,530 using attributes and methods. 95 00:05:20,530 --> 00:05:22,700 You'll find yourself using that setattr pattern, so 96 00:05:22,700 --> 00:05:25,510 make sure you add it to your notes and practice it a few times. 97 00:05:25,510 --> 00:05:27,770 In fact, let's do a code challenge or two around it. 98 00:05:27,770 --> 00:05:31,270 Then come right back for a serious talk about one of the hardest parts of object 99 00:05:31,270 --> 00:05:32,850 oriented programming, design.