Encapsulation bundles related data and methods into a class while exposing only what users need. In practice, minimize the public interface so internal implementation details remain easier to change and use. section 8.3 section 8.0
Hide formatting behind a public operation
A Task class can expose complete while keeping format_note for internal use. The complete method updates the task and formats its note without requiring callers to invoke the helper directly. section 8.3
class Task:
def __init__(self, title, desc, urgency):
self.title = title
self.desc = desc
self.urgency = urgency
self._status = "created"
self.note = ""
def complete(self, note = ""):
self.status = "completed"
self.note = self.format_note(note)
def format_note(self, note):
formatted_note = note.title()
return formatted_note
Use a leading underscore for a protected status attribute and keep formatting as an implementation helper called by complete. section 8.3
Choose the simplest access-control technique that protects the class interface:
- Treat public attributes and methods as available to users inside and outside the class. section 8.3
- Use protected members for class and subclass implementation, keeping them out of the intended external interface. section 8.3
- Use private members when access should remain limited to the class itself. section 8.3
- Expose controlled read-only state with @property: store _status internally, update it through complete, and let users read status. section 8.3.3
- Prefer direct attribute access when no restriction is needed; avoid automatically adding setters and getters because that is not Pythonic here. section 8.3.5
Listing 8.7 Using the property decorator
class Task:
def __init__(self, title, desc, urgency):
self.title = title
self.desc = desc
self.urgency = urgency
self._status = "created"
@property
def status(self):
return self._status
def complete(self):
self._status = "completed"
A property exposes status like an attribute while complete changes the protected _status value. section 8.3.3
Listing 8.8 Read-only property
>>> task.status = "completed" # ERROR: AttributeError: can't set attribute 'status'
Attempting to assign directly to a read-only status property raises AttributeError, preserving the intended update path. section 8.3.3













