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'esternoAggiungi 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 consentitoUsa 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 sicuroProva ad accedere ai dati nascosti:
print(account.get_account_info()) # Owner: Alice, Account: ***3456
# print(account.__account_number) # AttributeError - hiddenL'attributo privato è alterato nel nome, ma è comunque tecnicamente accessibile:
# This works but violates information hiding:
print(account._BankAccount__account_number) # ACC123456Output:
Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456Punto 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.
Sfida
MedioIn 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.")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
1Fondamenti di OOP
File esterniIntroduzione a OOPClassi vs. oggettiIl parametro selfMetodiAttributiMetodo costruttore (__init__)Riepilogo - Calcolatrice semplice4Ereditarietà
Ereditarietà di baseLa funzione super()Sovrascrittura dei metodiEreditarietà multiplaOrdine di risoluzione dei metodiRiepilogo - Gerarchia dei dipendenti7Metodi speciali
Introduzione ai metodi magiciSovraccarico degli operatoriMetodi magici dei contenitoriRiepilogo - Lista personalizzata10Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneModello SingletonModello FactoryModello ObserverModello Strategy2Decoratori
Introduzione ai decoratoriDecoratore di proprietàDecoratore di metodo staticoDecoratore di metodo di classe5Polimorfismo
Ripasso dell'override dei metodiDuck typingClassi e metodi astrattiProgettazione delle interfacceRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàMixinMetodi statici e di classeDecorator di classeContext manager11Pattern di progettazione - Parte 2
Pattern dei comandiPattern adattatorePattern decoratorePattern metodo templatePattern statoPattern composito3Proprietà delle classi
Variabili di istanza e di classeDecorator delle proprietàAttributi privatiRiepilogo - Gestore di conti bancari6Incapsulamento
Membri pubblici, protetti e privatiModificatori di accessoOccultamento delle informazioniDecorator delle proprietà: avanzatiRipasso - Sistema di registri degli studenti12Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e UtenteSistema di prestitoFunzionalità di ricercaInterfaccia amministratoreTest e integrazioneEsercitati da solo: Compilatore Python online