4.1 Encapsulation in Python

  • Access modifier are useful to attain encapsulation
  • It is archived by access modifiers public, private, protected

Python does not have strong distinctions between private and public variables like Java does.

There is no private-ness in python, as one of Python principles says –> We're all adults

# They just follow convention
Single underscore `_`
    --> its suppose to be protected
Double underscore `__`
    --> Do not use this field directly

# It is called Name Mangling
  • Public Access Modifier
    • Eg: var
    • All member variables and methods are public by default in Python
    • And are accessible from outside the Class through an object of the class.
  • Protected Access Modifier
    • Eg: _var
    • These are accessible from outside the class but only in a class derived from it that is in the child class.
    • Should not be accessed directly, use @property to access the variable
  • Private Access Modifier
    • Eg: __var
    • These members are only accessible from within the class. No outside Access is allowed.
class Employee:
  def __init__(self, name, sal, var):
    self.name = name  # public attribute 
    self._sal = sal   # protected attribute
    self.__var = var  # private attribute

4.2 Program to illustrate access modifiers of a class

class Employee:
    def __init__(self, name, sal, var):
        self.name = name
        self._sal = sal
        self.__var = var

    @property
    def sal(self):
        return self._sal


ob = Employee('Amrit',10,20)
print(ob.name)

print(ob._sal) # Not recommended
print(ob.sal)

# print(ob.__var) # Not accessible
print(ob._Employee__var) # Not recommended
class Super:
    var1 = None
    _var2 = None
    __var3 = None

    def __init__(self, var1, var2, var3):
        self.var1 = var1
        self._var2 = var2
        self.__var3 = var3

    # public member function
    def displayPublicMembers(self):
        print("Public Data Member: ", self.var1)

    # protected member function
    def _displayProtectedMembers(self):
        print("Protected Data Member: ", self._var2)

    # private member function
    def __displayPrivateMembers(self):
        print("Private Data Member: ", self.__var3)

    # public member function
    def accessPrivateMembers(self):
        self.__displayPrivateMembers()


class Sub(Super):
    def __init__(self, var1, var2, var3):
        Super.__init__(self, var1, var2, var3)

    def accessProtectedMemebers(self):
        self._displayProtectedMembers()


# Working with parent class
if __name__ == "__main__":
    s1 = Super("public", 'protected', "private")
    print(s1.var1, s1._var2)
    print(s1._Super__var3)

    s1.displayPublicMembers()
    s1._displayProtectedMembers()
    
    # Error - Can't access
    # s1.__displayPrivateMembers() 

    s1._Super__displayPrivateMembers()        
# Working with subclass
if __name__ == "__main__":
    obj = Sub("Market", 4, "Shopping")
    print(obj.var1, obj._var2)

    # print(obj.__var3)  # Error
    # print(obj._Sub__var3) # Error
    print(obj._Super__var3)        

    obj.displayPublicMembers()
    obj._displayProtectedMembers()
    # obj.__displayPrivateMembers()  # Error
    # obj._Sub__displayPrivateMembers()  # Error
    obj._Super__displayPrivateMembers()  

    # fxn to access pvt and protected member
    obj.accessProtectedMemebers()
    obj.accessPrivateMembers()

4.3 Underscore

  • Single Leading Underscore
    • _var
    • Naming convention indicating a name is meant for internal use
    • Generally not enforced by the Python interpreter (except in wildcard imports) and meant as a hint to the programmer only.
  • Single Trailing Underscore
    • var_
    • Used by convention to avoid naming conflicts with Python keywords.
  • Double Leading Underscore
    • __var
    • Triggers name mangling when used in a class context. Enforced by the Python interpreter.
  • Double Leading and Trailing Underscore
    • __var__
    • Indicates special methods defined by the Python language.
    • Avoid this naming scheme for your own attributes.
  • Single Underscore
    • _
    • Sometimes used as a name for temporary or insignificant variables (“don’t care”).
    • Also: The result of the last expression in a Python REPL.

Reference