Menu
Coddy logo textTech

Public, Protected, Private Member

Teil des Abschnitts Object Oriented Programming der Python-Journey von Coddy — Lektion 28 von 64.

Python hat drei Stufen der Zugriffskontrolle für Klassenmitglieder: public, protected und private. Diese steuern, wie auf Attribute und Methoden zugegriffen werden kann.

Hier ist ein Beispiel für eine Klasse mit allen drei Zugriffsebenen:

class BankAccount:
    def __init__(self, owner, balance, account_id):
        self.owner = owner           # Öffentlich - überall zugänglich
        self._balance = balance      # Geschützt - interne Verwendung
        self.__account_id = account_id  # Privat - nur Klasse
    
    def deposit(self, amount):       # Öffentliche Methode
        self._balance += amount
    
    def _calculate_interest(self):   # Geschützte Methode
        return self._balance * 0.02
    
    def __validate_transaction(self, amount):  # Private Methode
        return amount > 0 and amount <= self._balance

Greifen Sie von überall auf öffentliche Member zu:

account = BankAccount("Alice", 1000, "12345")
print(account.owner)        # Alice
account.deposit(500)        # Funktioniert einwandfrei

Zugriff auf geschützte Member (einfacher Unterstrich - nur Konvention):

print(account._balance)     # 1500 - funktioniert, wird aber nicht empfohlen
result = account._calculate_interest()  # Funktioniert, wird aber nicht empfohlen
print(result)               # 30.0

Versuchen Sie, auf private Member zuzugreifen (doppelter Unterstrich - Name Mangling):

# Das wird nicht funktionieren:
# print(account.__account_id)  # AttributeError

# Aber das funktioniert (Name Mangling):
print(account._BankAccount__account_id)  # 12345

Erstellen Sie eine Unterklasse, um den geschützten (protected) gegenüber dem privaten (private) Zugriff zu zeigen:

class SavingsAccount(BankAccount):
    def show_balance(self):
        return self._balance        # Geschützt - in der Unterklasse zugänglich
    
    def show_id(self):
        # return self.__account_id  # Das wird nicht funktionieren - privat
        return "Cannot access private member"
savings = SavingsAccount("Bob", 2000, "67890")
print(savings.show_balance())  # 2000
print(savings.show_id())       # Kann nicht auf privates Mitglied zugreifen

Ausgabe:

Alice
30.0
12345
2000
Cannot access private member

Kernpunkt: Öffentliche Member haben kein Präfix und sind überall zugänglich. Geschützte Member verwenden einen einfachen Unterstrich (_) und sollten nur innerhalb der Klassenhierarchie verwendet werden. Private Member verwenden einen doppelten Unterstrich (__) und werden für einen stärkeren Schutz durch Name Mangling verändert. Pythons Zugriffskontrolle basiert auf Konventionen und wird nicht streng erzwungen.

challenge icon

Aufgabe

Mittel

In dieser Challenge implementieren Sie eine BankAccount-Klasse, die die korrekte Verwendung von public, protected und private Zugriffsebenen in Python demonstriert.

  • bankaccount.py – Enthält die Klassendefinition mit TODO-Kommentaren, die Sie bei der Implementierung unterstützen.
  1. Folgen Sie den TODO-Kommentaren in bankaccount.py, um die erforderliche Funktionalität zu implementieren.
  2. Implementieren Sie die korrekten Zugriffsebenen (public, protected, private) wie angegeben.
  3. Stellen Sie sicher, dass alle Methoden Grenzfälle angemessen behandeln (negative Einzahlungen usw.).

Spickzettel

Python hat drei Zugriffskontrollstufen für Klassenmitglieder:

  • Öffentlich (Public): Kein Präfix, überall zugänglich
  • Geschützt (Protected): Einzelner Unterstrich (_), interne Verwendung innerhalb der Klassenhierarchie
  • Privat (Private): Doppelter Unterstrich (__), Name-Mangling für Zugriff nur innerhalb der Klasse
class BankAccount:
    def __init__(self, owner, balance, account_id):
        self.owner = owner           # Öffentlich
        self._balance = balance      # Geschützt
        self.__account_id = account_id  # Privat
    
    def deposit(self, amount):       # Öffentliche Methode
        self._balance += amount
    
    def _calculate_interest(self):   # Geschützte Methode
        return self._balance * 0.02
    
    def __validate_transaction(self, amount):  # Private Methode
        return amount > 0 and amount <= self._balance

Zugriff auf Mitglieder:

account = BankAccount("Alice", 1000, "12345")

# Öffentlicher Zugriff
print(account.owner)        # Funktioniert einwandfrei

# Geschützter Zugriff (funktioniert, wird aber nicht empfohlen)
print(account._balance)     # 1500

# Privater Zugriff (Name Mangling)
print(account._BankAccount__account_id)  # 12345

In Unterklassen:

class SavingsAccount(BankAccount):
    def show_balance(self):
        return self._balance        # Geschützt - zugänglich
    
    def show_id(self):
        # return self.__account_id  # Privat - nicht zugänglich
        return "Cannot access private member"

Probier es selbst

from bank_account import BankAccount

# Umfassender Testfall-Handler
test_case = input()

if test_case == "basic_test":
    # Test der Basisfunktionalität
    account = BankAccount("John Doe", "12345")
    print(account.account_holder)  # Öffentliches Attribut
    print(account.deposit(100))    # Öffentliche Methode
    print(account.get_balance())   # Öffentliche Methode

elif test_case == "transaction_count":
    # Testen eines geschützten Attributs
    account = BankAccount("Jane Smith", "67890")
    account.deposit(50)
    account.deposit(100)
    account.deposit(200)
    print(account._transaction_count)  # Geschütztes Attribut
    print(account.get_balance())

elif test_case == "invalid_deposit":
    # Testen der Validierung in der Einzahlungsmethode
    account = BankAccount("Bob Johnson", "54321")
    print(account.deposit(-50))  # Sollte None zurückgeben
    print(account.deposit(0))    # Sollte None zurückgeben
    print(account.deposit(75))   # Sollte 75 zurückgeben
    print(account.get_balance())

elif test_case == "private_access":
    # Testen des Zugriffs auf private Attribute
    account = BankAccount("Alice Brown", "98765")
    try:
        print(account.__balance)  # Dies wird einen AttributeError auslösen
    except AttributeError:
        pass
    
    try:
        print(account.__account_number)  # Dies wird einen AttributeError auslösen
    except AttributeError:
        pass
    
    print("Private attributes are not directly accessible")
    account.deposit(500)
    print(account.get_balance())  # Zugriff über öffentliche Methode

elif test_case == "name_mangling":
    # Demonstration von Name Mangling für private Attribute
    account = BankAccount("Charlie Green", "13579")
    print(account._BankAccount__balance)        # Zugriff auf privates Attribut über Name Mangling
    print(account._BankAccount__account_number)  # Zugriff auf privates Attribut über Name Mangling
    account.deposit(300)
    print(account._BankAccount__balance)  # Sollte den aktualisierten Kontostand anzeigen

elif test_case == "multiple_accounts":
    # Testen mehrerer Konten
    account1 = BankAccount("David White", "24680")
    account2 = BankAccount("Eva Black", "86420")
    account3 = BankAccount("Frank Red", "97531")
    
    account1.deposit(150)
    account2.deposit(250)
    account2.deposit(50)
    account3.deposit(500)
    account3.deposit(300)
    account3.deposit(200)
    
    print(f"{account1.account_holder}: {account1.get_balance()}")
    print(f"{account2.account_holder}: {account2.get_balance()}")
    print(f"{account3.account_holder}: {account3.get_balance()}")
    
    print(f"Account 1 transactions: {account1._transaction_count}")
    print(f"Account 2 transactions: {account2._transaction_count}")
    print(f"Account 3 transactions: {account3._transaction_count}")

elif test_case == "stress_test":
    # Performance-Test mit vielen Transaktionen
    account = BankAccount("Stress Tester", "11111")
    for _ in range(1000):
        account.deposit(1)
    print(f"Final balance: {account.get_balance()}")
    print(f"Transaction count: {account._transaction_count}")
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Object Oriented Programming