~ OOP,Classes,Python,Understanding encapsulation in Python

A look at encapsulation in Python

*Please Note* - all presentations and code challenges+solutions are available to subscribing members. It's now time to look at the pillar of object orientated programming referred to as encapsulation. Encapsulation, very simply, refers to information/data hiding and hiding the complexity of the details from the user, perhaps by presenting a more simple and user-friendly interface via which to interact with the class. This is a key concept and we will be looking at every day examples which demonstrate how you come across the concept of encapsulation all the time! In addition to this we will be looking at the various conventions for access specifiers, private, protected and public with a discussion about how these actually work in python as compared to in other languages. Do watch the video below which explains the concept, goes through the coding example and then attempt the challenges which are presented inside the code yourself


Code and Challenge #1

Real world example: As a car driver, when you want to stop because an old lady just ran across the
road, you simply need to know how to press the break, you do NOT need to know the internal
mechanisms and methods that are taking place in order for the break to function. In programming
encapsulation is the process of hiding the implementation and complex details from the user.

When you define attributes and methods they can be specified as public, protected or private.
Access Specification types: Private, Public, Protected.
Metaphor:  Say you write a secret on a piece of paper and throw it outside your house on the streets.
It's PUBLIC knowledge now! If you keep the piece of paper inside your house, well, it's accesible only
to you and anyone in your house. (PROTECTED) Finally, if you keep the piece of paper safely in your room
then it is entirely PRIVATE, accessible only to you! 

Important Note:
Unlike many other languages, Python does not force access specifiers, but rather they can be used as a naming convention
that has used by developers over the years. If you declare something as private, you are informing developers
(and reminding yourself) that this attribute is to be only used within that class, and nowhere else. In practice, the attribute
can be accessed as Python doesn't force this....

What are the naming conventions (access specifiers) used for private, protected and public members ?
Python does not force
Private -> __memberName (attributes/methods only accessible only by your own class and not any derived class)
Protected -> _memberName (accessible only by your class and derived class)
Public -> memberName (accessible to your class, to a derived class, and anywhere outside the derived class)

 How is name mangling done for private members by Python ?
Name mangling is done by prepending the member name with an underscore and class name.

TASK: Create your own class and example that demonstrates encapsulation
Play around with the code provided to examine how it really works.
#======PRIVATE and PROTECTED ATTRIBUTE (remember in practice, it will actually be accessible publically, but a good developer will make note of the suggestion of accessibility
class Car:
    _color="Black" #creating a protected attribute accessible by this class and any derived class

class Mazda(Car):
    def __init__(self):
        print("Protected Attribute colour:", self._color)
print("Public attribute Number of Wheels:",car.noOfWheels)
print("Private Attribute year of manufacture:",car.__secretcode)
Output will be : AttributeError: 'Car' object has no attribute '__yearofManufacture'
This error can be got round in Python but you are not meant to do so!

Download Python 3 here: