Menu
CoddyTech

Сокрытие информации

Часть раздела Объектно-ориентированное программирование путешествия по 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 — публичный доступ разрешён

Используйте контролируемые методы для защищённых данных:

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

Ключевой момент: сокрытие информации защищает внутренние данные, делая их приватными или защищёнными, а затем предоставляя контролируемый доступ к ним через публичные методы. Это предотвращает прямое изменение конфиденциальных данных и обеспечивает целостность данных благодаря проверке в методах доступа.

challenge icon

Задание

Средне

В этом задании ты реализуешь защищённую систему обмена сообщениями и проведёшь комплексное тестирование, чтобы проверить своё решение.

Тебе нужно отредактировать 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.")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор Python