Attribution
This page originates from TeachBooks/learn-programming, version: mude-2025
import matplotlib
if not hasattr(matplotlib.RcParams, "_get"):
matplotlib.RcParams._get = dict.get
1.3. Encapsulation#
As we have mentioned before using dictionaries is not useful to create objects that consist of several attributes. Encapsulation entails the wrapping of attributes and methods within one unit. This is beneficial as it enables engineers to write code that is easy to maintain. For example, if you add a new attribute or a method to a class, you will not need to update all your objects, but only the class itself.
A nice feature that encapsulation provides is private attributes and private methods. Those are units, which are meant to only be used internally in a class and not accessed outside of it. By convention programmers should not access them via the object. Furthermore, in order to create a private attribute or a private method, you need to put 2 leading underscores (_) before their name.
You can think of the __init__ method for an example. You are not supposed to call the method, as it is automatically called when you create a new object. Furthermore, note that it has 2 leading and 2 trailing underscores. This is meant to show that this method is resereved in Python. Therefore, you should not make attributes or methods that have both leading and trailing underscores, because you may mess up how Python works. Besides the __init__ method, there are more built-in methods that start and end with 2 underscores. These are called magic methods, and determine the behaviour when certain operations (for example: +, - or print()) are performed on an object.
Have a look at the Rocket class below, which contains a private attribute creation_date. We will call this attribute __creation_date to tell Python that we want it to be private. This attribute is set inside the __init__ method and should not be accessed outside the class unless we create a method, which returns it:
from math import sqrt
import datetime
class Rocket:
# Rocket simulates a rocket ship for a game,
# or a physics simulation.
def __init__(self, x=0, y=0):
# Each rocket has an (x,y) position.
self.x = x
self.y = y
self.__creation_time = datetime.datetime.now()
def move_rocket(self, x_increment=0, y_increment=1):
# Move the rocket according to the paremeters given.
# Default behavior is to move the rocket up one unit.
self.x += x_increment
self.y += y_increment
def get_distance(self, other_rocket):
# Calculates the distance from this rocket to another rocket,
# and returns that value.
distance = sqrt((self.x-other_rocket.x)**2+(self.y-other_rocket.y)**2)
return distance
def get_creation_time(self):
# Returns the time the Rocket was made.
return self.__creation_time
# Make a rocket.
rocket_0 = Rocket()
# Try to get the creation time via a method.
date = rocket_0.get_creation_time()
print(f"Rocket was made in: {date}")
# Try to get the creation time directly.
date = rocket_0.__creation_time
print(f"Rocket was made in: {date}")
Rocket was made in: 2025-10-30 11:12:47.265953
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[1], line 38
35 print(f"Rocket was made in: {date}")
37 # Try to get the creation time directly.
---> 38 date = rocket_0.__creation_time
39 print(f"Rocket was made in: {date}")
AttributeError: 'Rocket' object has no attribute '__creation_time'
As seen in the example above, we can only access __creation_time via the method get_creation_time and get an AttributeError if we attempt to directly use the dot notation on the object rocket_0.