Menu
Coddy logo textTech

Occultamento delle informazioni

Fa parte della sezione Programmazione orientata agli oggetti del percorso Python di Coddy. Lezione 30 di 64.

Il nascondimento delle informazioni limita l'accesso diretto ai componenti degli oggetti, richiedendo che tutte le interazioni avvengano tramite interfacce ben definite. Questo protegge i dati interni dagli accessi non autorizzati.

Ecco un esempio di una classe con diversi livelli di occultamento delle informazioni:

class BankAccount:
    def __init__(self, owner, initial_balance):
        self.owner = owner                    # Pubblico - accessibile direttamente
        self._balance = initial_balance       # Protetto - per uso interno
        self.__account_number = "ACC123456"   # Privato - nascosto all'esterno

Aggiungi metodi che forniscano un accesso controllato ai dati nascosti:

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):
        # Modo sicuro per mostrare una parte dei dati privati
        return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"

Usa la classe tramite la sua interfaccia pubblica:

account = BankAccount("Alice", 1000)

Accedi direttamente ai dati pubblici:

print(account.owner)  # Alice - accesso pubblico consentito

Usa metodi controllati per i dati protetti:

print(account.get_balance())  # 1000 - accesso controllato
account.deposit(500)
print(account.get_balance())  # 1500 - saldo modificato in modo sicuro

Prova ad accedere ai dati nascosti:

print(account.get_account_info())  # Owner: Alice, Account: ***3456
# print(account.__account_number)  # AttributeError - hidden

L'attributo privato è alterato nel nome, ma è comunque tecnicamente accessibile:

# This works but violates information hiding:
print(account._BankAccount__account_number)  # ACC123456

Output:

Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456

Punto chiave: l'occultamento delle informazioni protegge i dati interni rendendoli privati o protetti, quindi fornisce un accesso controllato tramite metodi pubblici. Questo impedisce la manipolazione diretta dei dati sensibili e garantisce l'integrità dei dati tramite la convalida nei metodi di accesso.

challenge icon

Sfida

Medio

In questa sfida, implementerai un sistema di messaggistica sicuro con test completi per convalidare la tua soluzione.

Devi modificare securemessenger.py per implementare la classe SecureMessenger seguendo i principi di information hiding. Il file contiene commenti TODO dettagliati per guidare la tua implementazione.

I requisiti principali includono:

  • Incapsulamento corretto delle credenziali e dei messaggi
  • Autenticazione prima di consentire le operazioni sui messaggi
  • Monitoraggio della sicurezza tramite il tracciamento dei tentativi di accesso
  • Messaggi restituiti precisi, come specificato nei TODO

Provalo tu

from securemessenger import SecureMessenger

# Gestore dei casi di test
test_case = input()
if test_case == "default_test":
    # Caso di test standard del problema originale
    messenger = SecureMessenger("user1")
    
    # Prova ad aggiungere messaggi prima dell'accesso
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # Prova ad accedere con una password errata
    print(messenger.login("wrong_pass"))
    
    # Accedi con la password corretta
    print(messenger.login("secure123"))
    
    # Aggiungi messaggi dopo aver effettuato l'accesso
    print(messenger.add_message("Hello World!"))
    print(messenger.add_message("Secure Message"))
    
    # Recupera i messaggi
    print(messenger.get_messages())
    
    # Controlla i tentativi di accesso
    print(messenger.get_login_attempts())
elif test_case == "custom_password":
    # Test con una password personalizzata
    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 di più tentativi di accesso
    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":
    # Gestione di Test message
    messenger = SecureMessenger("user3")
    print(messenger.login("secure123"))
    
    # Aggiungi più messaggi
    messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
    for msg in messages:
        print(messenger.add_message(msg))
    
    # Verifica tutti i messaggi
    print(messenger.get_messages())
elif test_case == "empty_messages":
    # Testa il caso in cui non ci sono messaggi
    messenger = SecureMessenger("user4")
    print(messenger.login("secure123"))
    print(messenger.get_messages())
elif test_case == "access_without_login":
    # Testa l'accesso senza aver effettuato il login
    messenger = SecureMessenger("user5")
    print(messenger.add_message("Unauthorized message"))
    print(messenger.get_messages())
elif test_case == "attribute_privacy":
    # Testa la riservatezza degli attributi
    messenger = SecureMessenger("user6")
    
    # Attributo pubblico
    print(f"Public username: {messenger.username}")
    
    # Attributi privati: dovrebbero generare 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":
    # Questo test richiede di estendere la classe con un metodo di logout
    # Ai fini del test, creeremo una sottoclasse con funzionalità di 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":
    # Stress test con molti messaggi
    messenger = SecureMessenger("user8")
    print(messenger.login("secure123"))
    
    # Aggiungi 100 messaggi
    for i in range(1, 101):
        messenger.add_message(f"Message {i}")
    
    # Verifica il numero di messaggi
    messages = messenger.get_messages()
    newline_char = '\n'  # Memorizza il carattere di nuova riga in una variabile
    message_count = len(messages.split(newline_char))
    print(f"Added 100 messages. Retrieved {message_count} messages.")
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Python online