class Circle():
def __init__(self, name: str, radius: int):
self.name: str = name
self._radius: int = radius #21
@property
def radius_accessor(self):
'''
@property
def radius_accessor(self):
The name of this method becomes attribute name of an instance, or
(more accurately the attribute accesor?)
to access the private attribute we want
(usually defined in class init(): self._private_attribute)
e.g. Suppose we have circle instance (type Circle)
with private attr: circle._radius.
Instead of accessing it directly (circle._radius)
which we can but we shouldn't, we access it via the getter created here
via @property with: circle.radius_accessor
i.e. circle.radius_accessor is getter for circle._radius
Therefore, a more suitable method name for this getter would be:
def radius():
i.e.
@property
def radius(self) allows us to access circle._radius via circle.radius
'''
return self._radius
@property
def radius(self):
'''explained in radius_accessor()'''
return self._radius
def __repr__(self):
return f"Circle(name={self.name!r}, _radius={self._radius!r})"
def __str__(self):
return f"It's a circle named {self.name!r} with a round belly of {self._radius} centimeters!"
1. Introduction
This post is specifically related to Issue #22 of tonyjustdevs/learning_designpatterns:
2. Background
Encapsulation is the:
- bundling of data (attributes) and
- methods (functions)
- into a single unit (class) and
- restricting direct access to some of the object’s components.
Purpose:
- To hide implementation details and
- enforce controlled access to an object’s data.
Key Components:
- Access modifiers (private, protected, public in some languages) and
- Getters & Setters for controlled access.
2.1 Getters and Setters:
Definition: These are methods used to retrieve (get) and update (set) private or protected attributes of a class.
Purpose: To provide controlled access to the attributes while maintaining encapsulation.
Relation to Encapsulation: They implement the idea of “controlled access” in encapsulation.
They are tools to implement encapsulation.
3. Things To Do
- Create
Circle
class - Instantiate a
circle
instance - Test attribute access directly:
circle._radius
- Test attribute access via getter1:
circle.radius_accessor
- Test attribute access via getter2:
circle.radius
4. Create Circle
class
- create private variable:
_radius
- create getter method:
radius_accessor()
- decorate with:
@property
4.1 Notes for Tony
print(Circle.radius_accessor.__doc__)
@property
def radius_accessor(self):
The name of this method becomes attribute name of an instance, or
(more accurately the attribute accesor?)
to access the private attribute we want
(usually defined in class init(): self._private_attribute)
e.g. Suppose we have circle instance (type Circle)
with private attr: circle._radius.
Instead of accessing it directly (circle._radius)
which we can but we shouldn't, we access it via the getter created here
via @property with: circle.radius_accessor
i.e. circle.radius_accessor is getter for circle._radius
Therefore, a more suitable method name for this getter would be:
def radius():
i.e.
@property
def radius(self) allows us to access circle._radius via circle.radius
5. Instantiate a circle
instance
= Circle("Sir Cumference",50)
circle print(f"{circle}") # calls __str__
It's a circle named 'Sir Cumference' with a round belly of 50 centimeters!
# defaults to __repr__ circle
Circle(name='Sir Cumference', _radius=50)
6. Test attribute access directly: circle._radius
# still works - because private attr dont exist in python circle._radius
50
7. Test attribute access via getter1: circle.radius_accessor
circle.radius_accessor
50
8. Test attribute access via getter2: circle.radius
circle.radius
50