信息隐藏
本课属于 Coddy Python 学习旅程的“面向对象编程”单元。第 30 课,共 64 课。
信息隐藏会限制对对象组件的直接访问,要求所有交互都通过定义明确的接口进行。这样可以保护内部数据,防止未经授权的访问。
下面是一个展示不同级别信息隐藏的类示例:
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # 公有:可以直接访问
self._balance = initial_balance # 受保护:供内部使用
self.__account_number = "ACC123456" # 私有:外部无法访问添加用于受控访问隐藏数据的方法:
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):
# 安全地展示部分私有数据
return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"通过类的公共接口使用它:
account = BankAccount("Alice", 1000)直接访问公共数据:
print(account.owner) # Alice,公开访问没问题使用受控方法访问受保护的数据:
print(account.get_balance()) # 1000,受控访问
account.deposit(500)
print(account.get_balance()) # 1500,余额已安全更新试着访问隐藏数据:
print(account.get_account_info()) # 所有者:Alice,账户:***3456
# print(account.__account_number) # AttributeError:属性已隐藏私有属性经过名称改写,但在技术上仍然可以访问:
# 这样可以运行,但违反了信息隐藏原则:
print(account._BankAccount__account_number) # ACC123456输出:
Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456要点:信息隐藏通过将内部数据设为私有或受保护,然后通过公共方法提供受控访问来保护内部数据。这可以防止直接操作敏感数据,并通过访问方法中的验证确保数据完整性。
挑战
中等在这个挑战中,你将实现一个安全的消息系统,并通过全面测试来验证答案。
你需要编辑 securemessenger.py,按照信息隐藏原则实现 SecureMessenger 类。文件中包含详细的 TODO 注释,可指导你完成实现。
主要要求包括:
- 妥善封装凭据和消息
- 进行消息操作前先完成身份验证
- 通过跟踪登录尝试次数来监控安全性
- 按照 TODO 中的说明准确返回消息
亲手试试
from securemessenger import SecureMessenger
# 测试用例处理
test_case = input()
if test_case == "default_test":
# 原题中的标准测试用例
messenger = SecureMessenger("user1")
# 尝试在登录前添加消息
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# 尝试用错误密码登录
print(messenger.login("wrong_pass"))
# 用正确密码登录
print(messenger.login("secure123"))
# 登录成功后添加消息
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# 获取消息
print(messenger.get_messages())
# 检查登录尝试次数
print(messenger.get_login_attempts())
elif test_case == "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":
# 测试多次尝试登录
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 管理
messenger = SecureMessenger("user3")
print(messenger.login("secure123"))
# 添加多条消息
messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
for msg in messages:
print(messenger.add_message(msg))
# 验证所有消息
print(messenger.get_messages())
elif test_case == "empty_messages":
# 测试消息为空的情况
messenger = SecureMessenger("user4")
print(messenger.login("secure123"))
print(messenger.get_messages())
elif test_case == "access_without_login":
# 测试未登录时的访问
messenger = SecureMessenger("user5")
print(messenger.add_message("Unauthorized message"))
print(messenger.get_messages())
elif test_case == "attribute_privacy":
# 测试属性的私有性
messenger = SecureMessenger("user6")
# 公共属性
print(f"Public username: {messenger.username}")
# 私有属性:访问这些属性应引发 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":
# 这个测试需要为类添加 logout 方法
# 为了测试,我们会创建一个具有登出功能的子类
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":
# 用大量消息进行压力测试
messenger = SecureMessenger("user8")
print(messenger.login("secure123"))
# 添加 100 条消息
for i in range(1, 101):
messenger.add_message(f"Message {i}")
# 核对消息数量
messages = messenger.get_messages()
newline_char = '\n' # 将换行符存入变量
message_count = len(messages.split(newline_char))
print(f"Added 100 messages. Retrieved {message_count} messages.")这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Python 在线编译器