Information Hiding
Part of the Object Oriented Programming section of Coddy's Python journey — lesson 30 of 64.
Information hiding restricts direct access to object components, requiring all interactions to occur through well-defined interfaces. This protects internal data from unauthorized access.
Here is an example of a class with different levels of information hiding:
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Public - can be accessed directly
self._balance = initial_balance # Protected - internal use
self.__account_number = "ACC123456" # Private - hidden from outsideAdd methods that provide controlled access to hidden data:
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner
self._balance = initial_balance
self.__account_number = "ACC123456"
def deposit(self, amount):
if amount > 0:
self._balance += amount
return True
return False
def withdraw(self, amount):
if amount > 0 and amount <= self._balance:
self._balance -= amount
return True
return False
def get_balance(self):
return self._balance
def get_account_info(self):
# Safe way to show partial private data
return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"Use the class through its public interface:
account = BankAccount("Alice", 1000)Access public data directly:
print(account.owner) # Alice - public access OKUse controlled methods for protected data:
print(account.get_balance()) # 1000 - controlled access
account.deposit(500)
print(account.get_balance()) # 1500 - balance changed safelyTry to access hidden data:
print(account.get_account_info()) # Owner: Alice, Account: ***3456
# print(account.__account_number) # AttributeError - hiddenThe private attribute is name-mangled but still technically accessible:
# This works but violates information hiding:
print(account._BankAccount__account_number) # ACC123456Output:
Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456Key Point: Information hiding protects internal data by making it private or protected, then providing controlled access through public methods. This prevents direct manipulation of sensitive data and ensures data integrity through validation in the access methods.
Challenge
MediumIn this challenge, you'll implement a secure messaging system with comprehensive testing to validate your solution.
You need to edit securemessenger.py to implement the SecureMessenger class following information hiding principles. The file contains detailed TODO comments to guide your implementation.
Key requirements include:
- Proper encapsulation of credentials and messages
- Authentication before allowing message operations
- Security monitoring through login attempt tracking
- Precise return messages as specified in the TODOs
Cheat sheet
Information hiding restricts direct access to object components through access modifiers:
public- accessible directly (no underscore)_protected- internal use (single underscore)__private- hidden from outside (double underscore)
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Public
self._balance = initial_balance # Protected
self.__account_number = "ACC123456" # PrivateProvide controlled access through public methods:
def get_balance(self):
return self._balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
return True
return FalsePrivate attributes are name-mangled but still accessible:
# Violates information hiding but works:
print(account._BankAccount__account_number)Try it yourself
from securemessenger import SecureMessenger
# Test case handler
test_case = input()
if test_case == "default_test":
# Standard test case from original problem
messenger = SecureMessenger("user1")
# Try to add messages before login
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# Attempt login with wrong password
print(messenger.login("wrong_pass"))
# Login with correct password
print(messenger.login("secure123"))
# Add messages after successful login
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# Retrieve messages
print(messenger.get_messages())
# Check login attempts
print(messenger.get_login_attempts())
elif test_case == "custom_password":
# Test with custom password
messenger = SecureMessenger("admin", "admin123")
print(messenger.login("wrong_password"))
print(messenger.login("admin123"))
print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
# Test multiple login attempts
messenger = SecureMessenger("user2")
print(messenger.login("attempt1"))
print(messenger.login("attempt2"))
print(messenger.login("attempt3"))
print(messenger.login("secure123"))
print(messenger.get_login_attempts())
elif test_case == "message_management":
# Test message management
messenger = SecureMessenger("user3")
print(messenger.login("secure123"))
# Add multiple messages
messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
for msg in messages:
print(messenger.add_message(msg))
# Verify all messages
print(messenger.get_messages())
elif test_case == "empty_messages":
# Test empty messages case
messenger = SecureMessenger("user4")
print(messenger.login("secure123"))
print(messenger.get_messages())
elif test_case == "access_without_login":
# Test access without login
messenger = SecureMessenger("user5")
print(messenger.add_message("Unauthorized message"))
print(messenger.get_messages())
elif test_case == "attribute_privacy":
# Test attribute privacy
messenger = SecureMessenger("user6")
# Public attribute
print(f"Public username: {messenger.username}")
# Private attributes - these should raise AttributeError
try:
print(messenger.__password)
except AttributeError as e:
print("Password is private: AttributeError")
try:
print(messenger.__messages)
except AttributeError as e:
print("Messages are private: AttributeError")
try:
print(messenger.__login_attempts)
except AttributeError as e:
print("Login attempts are private: AttributeError")
try:
print(messenger.__is_logged_in)
except AttributeError as e:
print("Login status is private: AttributeError")
elif test_case == "login_logout_sequence":
# This test requires extending the class with a logout method
# For testing purposes, we'll create a subclass with logout functionality
class ExtendedMessenger(SecureMessenger):
def logout(self):
self._SecureMessenger__is_logged_in = False
return "Logged out successfully"
messenger = ExtendedMessenger("user7")
print(messenger.login("secure123"))
print(messenger.add_message("Test message"))
print(messenger.get_messages())
print(messenger.logout())
print(messenger.get_messages())
elif test_case == "stress_test":
# Stress test with many messages
messenger = SecureMessenger("user8")
print(messenger.login("secure123"))
# Add 100 messages
for i in range(1, 101):
messenger.add_message(f"Message {i}")
# Verify message count
messages = messenger.get_messages()
newline_char = '\n' # Store the newline character in a variable
message_count = len(messages.split(newline_char))
print(f"Added 100 messages. Retrieved {message_count} messages.")This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of OOP
External FilesIntroduction to OOPClasses vs ObjectsThe self ParameterMethodsAttributesConstructor Method (__init__)Recap - Simple Calculator4Inheritance
Basic InheritanceThe super() FunctionMethod OverridingMultiple InheritanceMethod Resolution OrderRecap - Employee Hierarchy7Special Methods
Magic Methods IntroductionOperator OverloadingContainer Magic MethodsRecap - Custom List10Design Patterns Part 1
Intro to design patternSingleton PatternFactory PatternObserver PatternStrategy Pattern2Decorators
Introduction to DecoratorsProperty DecoratorStatic Method DecoratorClass Method Decorator5Polymorphism
Method Overriding RevisitedDuck TypingAbstract Classes and MethodsInterface DesignRecap - Shape Calculator8Advanced OOP Concepts
Composition vs InheritanceMixinsStatic and Class MethodsClass DecoratorsContext Managers3Class Properties
Instance vs Class VariablesProperty DecoratorsPrivate AttributesRecap - Bank Account Manager6Encapsulation
Public, Protected, Private MemAccess ModifiersInformation HidingProperty Decorators AdvancedRecap - Student Records System12Project: Library Management
Project OverviewBook and User Classes