Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Classes and Objects
Lecture: Encapsulation and data hiding

Login or purchase this course to watch this video and the rest of the course contents.
0:01 Encapsulation and data hiding is a key building block for object oriented design.
0:04 And Python, being a very object oriented language,
0:06 or at least having great support for object oriented programming,
0:10 of course, has ways to do this.
0:12 But I would say it's less Pythonic to focus heavily on these ideas,
0:15 things like private variables, and what not with inside classes or protected variables
0:21 that only derived classes can see, things like this.
0:24 But let's look at it anyway.
0:26 So, over here we have a class called pet snake,
0:28 and you can give it a name and you can give it an age,
0:30 and you can supply this protected value but it builds it up as you create it
0:35 and possibly these changes over time, right,
0:37 this is a great simplification of anything you might really use.
0:39 And, like before, we have this string overwrite
0:42 where we can print out some information about this.
0:45 So here we can say here is my pat snake,
0:47 I want her called Slide, it's 6 years old,
0:49 and we can just print it out that will call this method,
0:52 we can also access its values directly here, so let's just run this,
0:56 great, here is my pet snake, age 6, looks like it has an age and a name backwards
1:00 but that's fine, and the protection level here, perfect.
1:03 There is nothing wrong with this class, it seems fine to me,
1:07 but what if we wanted the age and the name to be read only?
1:10 Once you have created a snake you can't change its name,
1:13 once you've created a snake you can't change its age,
1:15 other than possibly having some way to like give it a birthday or something like that.
1:19 First of all, let me switch these because this is kind of bugging me this is backwards,
1:23 so in Python, there is a way to do this and let's work with this protected value,
1:28 let's suppose that we would like this to be accessible to derive classes
1:31 but we want to indicate to the consumers of it,
1:34 hey you probably shouldn't be messing with this,
1:36 so let's just before we change it let's print it out over here,
1:39 so here we'll print it out and see everything is fine,
1:42 if you look at the warnings form PyCharm no warnings.
1:44 So the way that you indicate something should not be consumed
1:47 outside of the class or more generally outside modules,
1:50 sort of externally is to say _ (underscore) as the prefix.
1:53 So now if I say this, notice, this goes away,
1:56 obviously, because it doesn't exist, but we can put it back, that's fine,
2:00 this goes away because it doesn't exist, we can put it back,
2:03 but now we have this warning and PyCharm is saying
2:06 access to a protected member such and such of class
2:09 you probably shouldn't be doing this unless you know what you are doing.
2:12 However, this is just a warning, it still works.
2:16 Notice here we are reading the name and the age
2:18 but we just as well could we are going to say py.name=py.name.upper,
2:25 something like that,
2:27 so now we have Slide so we are actually changing the type, ok
2:29 and maybe I'll change this print statement order as well
2:32 here we go, Slide and Slide, capital.
2:34 So what if we don't want this to be possible,
2:36 we want read only access to this and we'd have to provide a way
2:39 to get to it which we'll get to later.
2:41 So the way you do that in Python is you double underscores,
2:46 and of course down here,
2:48 those names changed, let me put this back for just a second,
2:50 if we really want to make this change we can hit control t
2:53 and do double underscore and change it everywhere
2:56 control t save me some typing and be safer of course.
3:00 You can see it changes everywhere but down here
3:02 PyCharm is like not so sure this is going to work well for you,
3:05 unresolved reference, well, maybe it's just hiding from us,
3:08 maybe it's saying you know, you really shouldn't access this,
3:11 we are going to tell you that it's not there. If I say py.
3:14 and the only reason it thinks the name is there is because we are doing this line,
3:17 if I take this line away, there is no name,
3:20 and it thought that line was creating the thing called __name__ which it would have,
3:23 if we set it, you can see those don't show up, ok,
3:26 so now let's run it and see what happens.
3:29 Boom, pet snake has no thing called __name__
3:33 and yet if I hide this, it does seem to have __name__ so what is going on here?
3:39 So you really can't access it by name here,
3:42 so let's look, so we'll look inside of type and say what methods and fields
3:47 does it have with this thing called dir, so I can dir py
3:50 and ask what basically features do you have,
3:53 it'll show us all the various things here,
3:56 so if we come over and we look for here is our protected value,
4:01 let's go and add just one normal value,
4:03 so I'll just say self.normal=true, so here at the end is our normal value,
4:08 here is our protected one so we can't get to it we are just you probably shouldn't.
4:12 So here we are saying self.__age, self.__name and that seems to work,
4:17 but it's actually got this rewritten name where it's rewritten based on the type.
4:23 So technically, you could come over here and copy this out and access this,
4:28 and it certainly wouldn't look like what's written up here
4:31 and it would tell you you know, you probably should stay away from that.
4:33 This is how you do private fields within classes in Python,
4:36 here is how you do protected ones.
4:38 And of course, doing neither of those, makes it just a normal type.
4:41 Ok, so here is our pet snake in a graphic.
4:45 We saw if we wanted the age and the name to be completely private,
4:49 we use double underscores,
4:51 if we want to have a protected variable that we want to strongly encourage people
4:54 to stay away from, we use single underscores and you saw that we get warnings
4:58 on the linters and things like that,
5:00 so if we go and write some code that tries to access this type,
5:03 here we can see we are creating a pet snake called a py
5:06 we'll get to this property thing in a moment, if we want to say py._protected we can,
5:13 but that does give us a warning, if we try to say py.__age,
5:18 we saw that it crashes and basically that name doesn't exist,
5:22 it's technically rewritten to be kind of hidden
5:24 but normal access doesn't work for it.