Сокрытие данных
Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 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 - публичный доступ OKИспользуйте контролируемые методы для защищенных данных:
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 - скрытоПриватный атрибут подвергается искажению имен (name mangling), но технически он все еще доступен:
# Это работает, но нарушает инкапсуляцию (скрытие информации):
print(account._BankAccount__account_number) # ACC123456Вывод:
Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456Ключевой момент: Скрытие информации защищает внутренние данные, делая их private или protected, а затем предоставляя контролируемый доступ через публичные методы. Это предотвращает прямое манипулирование конфиденциальными данными и обеспечивает целостность данных за счет валидации в методах доступа.
Задание
СреднеВ этом испытании вы реализуете защищенную систему обмена сообщениями с комплексным тестированием для проверки вашего решения.
Вам нужно отредактировать securemessenger.py, чтобы реализовать класс SecureMessenger, следуя принципам сокрытия информации. Файл содержит подробные комментарии TODO, которые помогут вам в реализации.
Основные требования включают:
- Правильная инкапсуляция учетных данных и сообщений
- Аутентификация перед разрешением операций с сообщениями
- Мониторинг безопасности через отслеживание попыток входа
- Точные возвращаемые сообщения, как указано в TODO
Шпаргалка
Скрытие информации ограничивает прямой доступ к компонентам объекта с помощью модификаторов доступа:
public— доступен напрямую (без подчеркивания)_protected— для внутреннего использования (одиночное подчеркивание)__private— скрыт извне (двойное подчеркивание)
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Публичный
self._balance = initial_balance # Защищенный
self.__account_number = "ACC123456" # ПриватныйОбеспечьте контролируемый доступ через публичные методы:
def get_balance(self):
return self._balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
return True
return FalseПриватные атрибуты подвергаются искажению имен (name-mangling), но все еще остаются доступными:
# Нарушает скрытие информации, но работает:
print(account._BankAccount__account_number)Попробуйте сами
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":
# Тест управления сообщениями
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.")В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Object Oriented Programming
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыПараметр selfМетодыАтрибутыМетод-конструктор (__init__)Повторение — Простой калькулятор4Наследование
Базовое наследованиеФункция super()Переопределение методовМножественное наследованиеПорядок разрешения методовИтоги — Иерархия сотрудников7Специальные методы
Введение в магические методыПерегрузка операторовМагические методы контейнеровПовторение — Пользовательский список10Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy5Полиморфизм
Снова о переопределении методовУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовИтоги — Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияМиксиныСтатические методы и методы классаДекораторы классовМенеджеры контекста11Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн Компоновщик3Свойства классов
Переменные экземпляра и классаДекораторы свойствПриватные атрибутыИтоги — Менеджер банковского счета6Инкапсуляция
Public, Protected, Private члены классаМодификаторы доступаСокрытие данныхДекораторы property: продвинутый уровеньИтоги: Система учета студентов12Проект: Управление библиотекой
Обзор проектаКлассы Book и User