This is a two-part blog series on Encapsulation in Python:
Encapsulation in simplest terms is bundling the data and protecting it.
Precisely, with encapsulation
class Agent:
def __init__(self, name, age):
self.name = name
self.age = ageagent1 = Agent("Kamesh", 25)agent1<__main__.Agent at 0x7e652d090a10>
agent1.age25
agent1.age = -5agent1.age-5
This is a problem
agent1.age to something invalid. There's no protection.Although in Python, we can't make truly private variables, but we can discourage access using naming conventions.
_var = protected (internal use; not enforced)
__var = private (name mangling adds safety)
_
class Agent:
def __init__(self, name, age):
self.name = name
self._age = ageagent2 = Agent("Priya", 23)agent2._age23
agent2._age = -5agent2._age-5
__
class Agent:
def __init__(self, name, age):
self.name = name
self.__age = ageagent3 = Agent("Kritik", 22)agent3.__age--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /tmp/ipython-input-14-1681600426.py in <cell line: 0>() ----> 1 agent3.__age AttributeError: 'Agent' object has no attribute '__age'
You can't access the class variable directly because it's private.
However, you can still access it using name mangling by prefixing it with _ClassName.
agent3._Agent__age22
You see.. This is name mangling.
Name mangling is a process used by Python to internally change the name of a variable to avoid accidental access or override.
agent3.__age # AttributeError
agent3._Agent__age # Works due to name mangling;
# Syntax: `_ClassName__varName`
and and and, You can still access and manipulate mangled variables.
agent3._Agent__age = -5agent3._Agent__age-5
class Agent:
def __init__(self, name, age):
self.name = name
self.__age = age
def get_age(self): # This get method gives you access to variable from outside the class.
return self.__age
def set_age(self, age):
if age >= 0:
self.__age = age
else:
raise ValueError("Invalid age!")agent4 = Agent("Kritik", 22)agent4.__age--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) /tmp/ipython-input-20-638608875.py in <cell line: 0>() ----> 1 agent4.__age AttributeError: 'Agent' object has no attribute '__age'
You can't access the variables directly, but you can access them using method defined in class.
agent4.get_age()22
agent4.set_age(-5) # since -5 is not valid age value in our class raises error--------------------------------------------------------------------------- ValueError Traceback (most recent call last) /tmp/ipython-input-22-3620207664.py in <cell line: 0>() ----> 1 agent4.set_age(-5) # since -5 is not valid age value in our class raises error /tmp/ipython-input-18-2719234968.py in set_age(self, age) 11 self.__age = age 12 else: ---> 13 raise ValueError("Invalid age!") ValueError: Invalid age!
But, If you set valid age:
agent4.set_age(5)agent4.get_age()5
It works.
Hope by Now:
__var.get_ and set_ methods.get_ and set_ naming is a convention among python community, not a rule. You're free to use other method names.Note:
Happy Learning ☺️