Masquage d'informations
Fait partie de la section Object Oriented Programming du Journey Python de Coddy — leçon 30 sur 64.
Le masquage d'informations limite l'accès direct aux composants de l'objet, exigeant que toutes les interactions passent par des interfaces bien définies. Cela protège les données internes contre tout accès non autorisé.
Voici un exemple d'une classe avec différents niveaux de masquage d'informations :
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Public - accessible directement
self._balance = initial_balance # Protégé - usage interne
self.__account_number = "ACC123456" # Privé - masqué de l'extérieurAjoutez des méthodes qui fournissent un accès contrôlé aux données cachées :
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):
# Moyen sûr d'afficher des données privées partielles
return f"Owner: {self.owner}, Account: ***{self.__account_number[-4:]}"Utilisez la classe via son interface publique :
account = BankAccount("Alice", 1000)Accédez directement aux données publiques :
print(account.owner) # Alice - accès public OKUtilisez des méthodes contrôlées pour les données protégées :
print(account.get_balance()) # 1000 - accès contrôlé
account.deposit(500)
print(account.get_balance()) # 1500 - solde modifié en toute sécuritéEssayez d'accéder aux données cachées :
print(account.get_account_info()) # Propriétaire : Alice, Compte : ***3456
# print(account.__account_number) # AttributeError - cachéL'attribut privé subit un masquage de nom (name-mangling) mais reste techniquement accessible :
# Cela fonctionne mais viole le principe de masquage d'informations :
print(account._BankAccount__account_number) # ACC123456Sortie :
Alice
1000
1500
Owner: Alice, Account: ***3456
ACC123456Point clé : Le masquage d'informations protège les données internes en les rendant privées ou protégées, puis en fournissant un accès contrôlé via des méthodes publiques. Cela empêche la manipulation directe des données sensibles et garantit l'intégrité des données grâce à la validation dans les méthodes d'accès.
Défi
MoyenDans ce défi, vous allez implémenter un système de messagerie sécurisé avec des tests complets pour valider votre solution.
Vous devez modifier securemessenger.py pour implémenter la classe SecureMessenger en suivant les principes de masquage d'informations. Le fichier contient des commentaires TODO détaillés pour guider votre implémentation.
Les exigences clés incluent :
- Une encapsulation appropriée des identifiants et des messages
- Une authentification avant d'autoriser les opérations sur les messages
- Une surveillance de la sécurité via le suivi des tentatives de connexion
- Des messages de retour précis comme spécifié dans les TODO
Aide-mémoire
Le masquage d'informations restreint l'accès direct aux composants d'un objet via des modificateurs d'accès :
public- accessible directement (pas de tiret bas)_protected- utilisation interne (tiret bas simple)__private- masqué de l'extérieur (double tiret bas)
class BankAccount:
def __init__(self, owner, initial_balance):
self.owner = owner # Public
self._balance = initial_balance # Protégé
self.__account_number = "ACC123456" # PrivéFournissez un accès contrôlé via des méthodes publiques :
def get_balance(self):
return self._balance
def deposit(self, amount):
if amount > 0:
self._balance += amount
return True
return FalseLes attributs privés subissent un masquage de nom (name mangling) mais restent accessibles :
# Viole le masquage d'informations mais fonctionne :
print(account._BankAccount__account_number)Essayez vous-même
from securemessenger import SecureMessenger
# Gestionnaire de cas de test
test_case = input()
if test_case == "default_test":
# Cas de test standard du problème original
messenger = SecureMessenger("user1")
# Essayer d'ajouter des messages avant la connexion
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# Tentative de connexion avec un mauvais mot de passe
print(messenger.login("wrong_pass"))
# Connexion avec le bon mot de passe
print(messenger.login("secure123"))
# Ajouter des messages après une connexion réussie
print(messenger.add_message("Hello World!"))
print(messenger.add_message("Secure Message"))
# Récupérer les messages
print(messenger.get_messages())
# Vérifier les tentatives de connexion
print(messenger.get_login_attempts())
elif test_case == "custom_password":
# Test avec un mot de passe personnalisé
messenger = SecureMessenger("admin", "admin123")
print(messenger.login("wrong_password"))
print(messenger.login("admin123"))
print(messenger.get_login_attempts())
elif test_case == "multiple_login_attempts":
# Tester plusieurs tentatives de connexion
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":
# Tester la gestion des messages
messenger = SecureMessenger("user3")
print(messenger.login("secure123"))
# Ajouter plusieurs messages
messages = ["Message 1", "Message 2", "Message 3", "Message 4", "Message 5"]
for msg in messages:
print(messenger.add_message(msg))
# Vérifier tous les messages
print(messenger.get_messages())
elif test_case == "empty_messages":
# Tester le cas des messages vides
messenger = SecureMessenger("user4")
print(messenger.login("secure123"))
print(messenger.get_messages())
elif test_case == "access_without_login":
# Tester l'accès sans connexion
messenger = SecureMessenger("user5")
print(messenger.add_message("Unauthorized message"))
print(messenger.get_messages())
elif test_case == "attribute_privacy":
# Tester la confidentialité des attributs
messenger = SecureMessenger("user6")
# Attribut public
print(f"Public username: {messenger.username}")
# Attributs privés - ceux-ci devraient lever une exception 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":
# Ce test nécessite d'étendre la classe avec une méthode de déconnexion
# Pour les besoins du test, nous allons créer une sous-classe avec une fonctionnalité de déconnexion
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":
# Test de charge avec de nombreux messages
messenger = SecureMessenger("user8")
print(messenger.login("secure123"))
# Ajouter 100 messages
for i in range(1, 101):
messenger.add_message(f"Message {i}")
# Vérifier le nombre de messages
messages = messenger.get_messages()
newline_char = '\n' # Stocker le caractère de nouvelle ligne dans une variable
message_count = len(messages.split(newline_char))
print(f"Added 100 messages. Retrieved {message_count} messages.")Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Object Oriented Programming
1Les fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe paramètre selfMéthodesAttributsMéthode constructeur (__init__)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLa fonction super()Redéfinition de méthodeHéritage multipleOrdre de résolution des méthodesRécapitulatif - Hiérarchie des employés7Méthodes spéciales
Introduction aux méthodes magiquesSurcharge d'opérateursMéthodes magiques de conteneurRécapitulatif - Liste personnalisée10Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron Strategy2Décorateurs
Introduction aux décorateursDécorateur de propriétéDécorateur de méthode statiqueDécorateur de méthode de classe5Polymorphisme
Retour sur la redéfinition de méthodeDuck TypingClasses et méthodes abstraitesConception d'interfacesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageMixinsMéthodes statiques et de classeDécorateurs de classeGestionnaires de contexte11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Propriétés de classe
Variables d'instance vs variables de classeDécorateurs de propriétéAttributs privésRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Membres Publics, Protégés, PrivésModificateurs d'accèsMasquage d'informationsDécorateurs Property AvancésRécapitulatif - Système de Gestion d'Étudiants