Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Classes and Objects
Lecture: Do not write get_thing() set_thing()
0:01 One of the primary reasons people will write non Pythonic code
0:03 is they come from other languages that have other idioms
0:06 and they just move their code over and make them work
0:08 using the same former idioms and not really adopt the new Python ones.
0:11 So here we have some not so Pythonic pet that we've been playing with,
0:14 it's got some private fields, age and name,
0:16 we'd like a way for us to get the name and get the age but not set it,
0:20 here we wrote a get name and get age so that you can get those.
0:24 But this is not Pythonic at all, and when you use the code it's not pretty,
0:28 it looks something like this, so here we create a not so Pythonic pet,
0:31 it's going to be a cow called Betsy who is 4
0:33 and we can say she is named such and such
0:36 and is however many years old, so cow.get_name cow.get_age.
0:41 It doesn't have to be this way, let's see how it should be.
0:45 All right, so here is the Betsy code again, not so Pythonic,
0:48 we are doing this and this, let's go down to this pet snake type
0:51 that we are working with and do something different, do it better.
0:54 You should almost never write these getters and setters in Python,
0:57 instead, the much more natural way to work with this
1:00 would be to say py.name, py.age
1:04 as if they were a field, now this can be just accessing underlined variables,
1:08 these could be computed like in a shopping cart you could say cart.total
1:12 and maybe that just actually does a loop and adds up all of the items,
1:15 like as a consumer, you don't want to think of these as functions,
1:19 you want to think of them as just attributes of the class, right.
1:23 So, in Python instead of writing those getters and setters
1:26 we can say come over here and say I'd like to have a function called name
1:30 and this is going to return self.__name, now if I try to run this code,
1:36 and let's do the same for age,
1:41 and if I come down here and I write this code,
1:43 we are going to get something entirely unexpected,
1:45 what do you get if you say the name of a function- without parenthesis,
1:48 you get the bound method, bound to this object.
1:51 That's not what we wanted so then we have to say this, and that's not so pretty,
1:58 technically it works, but we are kind of back to the previous example
2:02 that was names for our getters,
2:05 so in Python we can use a decorator called a property decorator, from the built ins,
2:09 down here I can say actually this is not a regular method but a property
2:13 and now if I say py well if I say it far enough down, py. name and age
2:18 you can see the little p by there, and if I access it like this,
2:22 this actually just calls the function, beautiful, right, don't write getters, write this.
2:26 Suppose I want to be able to change the age but not the name,
2:29 if we try to set the age, right now it's read only obviously,
2:33 and it says can't set the attribute we've already got this read only property called age
2:38 but if we wanted to set the age we can come down here and write another function
2:41 called age that takes the value and we'll say self.age=value.
2:48 Now we give it another attribute up here we say age.setter,
2:52 now this is less delightful than just add property but that works.
2:57 So now we should be able to set the age and run it, first our sneak is 6, then 7,
3:02 so just to make it clear, these are actual function calls,
3:04 not just changing the underline property, I'll do a print, there,
3:09 so all right, two little prints that every time you execute this code
3:12 which could do anything we wanted to do we just happen to be
3:15 setting the underlined private field,
3:17 it will print this and then when we get it will print that.
3:19 So here you can see, here is my pet snake, all we are getting is age,
3:22 its name and age and such and such, setting the age, getting the age and so on.
3:28 And finally like I said, you can have computed properties,
3:32 aren't really backed by underline store, so here I could say let's have is protected,
3:39 we could do return true or false depending on how high the protection level is
3:42 so we'll say let's say self.protected level value is greater than 5,
3:46 so if it's greater than 5 the snake is protected if it's not then it's not, whatever that means.
3:51 so we'll just at the very end I'll print py. is protected
3:55 you can see this property read only property, run that, no, the snake is not protected.
4:01 All right, so this is not based on just returning something,
4:03 we can compute whatever we want to.
4:05 Properties are really useful very Pythonic
4:07 and I recommend that you make good use of them.
4:10 So let's see in a graphic how we evolve this, right, getter setter- bad idea.
4:14 In our Pythonic pet, our pet snake, we've got our age and name
4:19 and here we are writing a property that says get me the read only version of the name
4:23 and the read only version of the age.
4:25 We also saw we can make writers or setters for the properties,
4:29 as well as computed properties that are not just returning underlined fields.
4:33 So with this in place, we can write as a consumer of the class,
4:36 much more natural code.
4:38 If we create a pet, it's called py
4:40 and its name is py.name and its age is py.age.