Ocultação de Informação
Parte da seção Object Oriented Programming do Journey de Python da Coddy — lição 30 de 64.
A ocultação de informações restringe o acesso direto aos componentes do objeto, exigindo que todas as interações ocorram por meio de interfaces bem definidas. Isso protege os dados internos contra acesso não autorizado.
Aqui está um exemplo de uma classe com diferentes níveis de ocultação de informações:
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Público - pode ser acessado diretamente
self._balance = initial_balance # Protegido - uso interno
self.__account_number = "ACC123456" # Privado - oculto do exteriorAdicione métodos que forneçam acesso controlado a dados ocultos:
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):
# Forma segura de mostrar dados privados parciais
return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"Use a classe por meio de sua interface pública:
account = BankAccount("Alice", 1000)Acesse dados públicos diretamente:
print(account.owner) # Alice - acesso público OKUse métodos controlados para dados protegidos:
print(account.get_balance()) # 1000 - acesso controlado
account.deposit(500)
print(account.get_balance()) # 1500 - saldo alterado com segurançaTente acessar dados ocultos:
print(account.get_account_info()) # Proprietário: Alice, Conta: ***3456
# print(account.__account_number) # AttributeError - ocultoO atributo privado sofre name-mangling, mas ainda é tecnicamente acessível:
# Isso funciona, mas viola a ocultação de informações:
print(account._BankAccount__account_number) # ACC123456Saída:
Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456Ponto Chave: A ocultação de informações protege os dados internos ao torná-los privados ou protegidos, fornecendo acesso controlado por meio de métodos públicos. Isso impede a manipulação direta de dados sensíveis e garante a integridade dos dados por meio de validação nos métodos de acesso.
Desafio
MédioNeste desafio, você implementará um sistema de mensagens seguro com testes abrangentes para validar sua solução.
Você precisa editar o arquivo securemessenger.py para implementar a classe SecureMessenger seguindo os princípios de ocultação de informações (information hiding). O arquivo contém comentários TODO detalhados para guiar sua implementação.
Os requisitos principais incluem:
- Encapsulamento adequado de credenciais e mensagens
- Autenticação antes de permitir operações de mensagem
- Monitoramento de segurança através do rastreamento de tentativas de login
- Mensagens de retorno precisas conforme especificado nos TODOs
Folha de consulta
A ocultação de informações restringe o acesso direto aos componentes do objeto por meio de modificadores de acesso:
public- acessível diretamente (sem sublinhado)_protected- uso interno (sublinhado simples)__private- oculto do exterior (sublinhado duplo)
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Público
self._balance = initial_balance # Protegido
self.__account_number = "ACC123456" # PrivadoForneça acesso controlado por meio de métodos públicos:
def get_balance(self):
return self._balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
return True
return FalseAtributos privados sofrem "name mangling", mas ainda são acessíveis:
# Viola a ocultação de informações, mas funciona:
print(account._BankAccount__account_number)Experimente você mesmo
from securemessenger import SecureMessenger
# Manipulador de casos de teste
test_case = input()
if test_case == "default_test":
# Caso de teste padrão do problema original
messenger = SecureMessenger("user1")
# Tenta adicionar mensagens antes do login
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# Tentativa de login com senha incorreta
print(messenger.login("wrong_pass"))
# Login com a senha correta
print(messenger.login("secure123"))
# Adiciona mensagens após login bem-sucedido
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# Recupera mensagens
print(messenger.get_messages())
# Verifica tentativas de login
print(messenger.get_login_attempts())
elif test_case == "custom_password":
# Teste com senha personalizada
messenger = SecureMessenger("admin", "admin123")
print(messenger.login("wrong_password"))
print(messenger.login("admin123"))
print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
# Teste de múltiplas tentativas de login
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":
# Teste de gerenciamento de mensagens
messenger = SecureMessenger("user3")
print(messenger.login("secure123"))
# Adiciona múltiplas mensagens
messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
for msg in messages:
print(messenger.add_message(msg))
# Verifica todas as mensagens
print(messenger.get_messages())
elif test_case == "empty_messages":
# Teste para o caso de mensagens vazias
messenger = SecureMessenger("user4")
print(messenger.login("secure123"))
print(messenger.get_messages())
elif test_case == "access_without_login":
# Teste de acesso sem login
messenger = SecureMessenger("user5")
print(messenger.add_message("Unauthorized message"))
print(messenger.get_messages())
elif test_case == "attribute_privacy":
# Teste de privacidade de atributos
messenger = SecureMessenger("user6")
# Atributo público
print(f"Public username: {messenger.username}")
# Atributos privados - estes devem gerar 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":
# Este teste requer a extensão da classe com um método de logout
# Para fins de teste, criaremos uma subclasse com funcionalidade de 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":
# Teste de estresse com muitas mensagens
messenger = SecureMessenger("user8")
print(messenger.login("secure123"))
# Adiciona 100 mensagens
for i in range(1, 101):
messenger.add_message(f"Message {i}")
# Verifica a contagem de mensagens
messages = messenger.get_messages()
newline_char = '\n' # Armazena o caractere de nova linha em uma variável
message_count = len(messages.split(newline_char))
print(f"Added 100 messages. Retrieved {message_count} messages.")Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1Fundamentos de POO
Arquivos ExternosIntrodução à POOClasses vs ObjetosO Parâmetro selfMétodosAtributosMétodo Construtor (__init__)Recapitulação - Calculadora Simples4Herança
Herança BásicaA Função super()Sobrescrita de MétodoHerança MúltiplaOrdem de Resolução de MétodosRecapitulação - Hierarquia de Funcionários7Métodos Especiais
Introdução aos Métodos MágicosSobrecarga de OperadoresMétodos Mágicos de ContêinerRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução a Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão Strategy2Decoradores
Introdução aos DecoradoresDecorador de PropriedadeDecorador de Método EstáticoDecorador de Método de Classe5Polimorfismo
Sobrescrita de Método RevisitadaDuck TypingClasses e Métodos AbstratosDesign de InterfacesRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição vs HerançaMixinsMétodos Estáticos e de ClasseDecoradores de ClasseGerenciadores de Contexto11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Propriedades de Classe
Variáveis de Instância vs de ClasseDecoradores de PropriedadeAtributos PrivadosRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Membros Públicos, Protegidos e PrivadosModificadores de AcessoOcultação de InformaçãoProperty Decorators AvançadosRecapitulação - Sistema de Registro de Alunos12Projeto: Gerenciamento de Biblioteca
Visão Geral do ProjetoClasses Livro e Usuário