Python - Zugriffsmodifikatoren
Hallo dort, ambitionierte Python-Programmierer! Heute werden wir auf eine aufregende Reise in die Welt der Zugriffsmodifikatoren in Python eintauchen. Keine Sorge, wenn du neu bei der Programmierung bist; ich werde dich Schritt für Schritt durch dieses Konzept führen, mit vielen Beispielen und Erklärungen unterwegs. Also, lasst uns einsteigen!
Zugriffsmodifikatoren in Python
In der objektorientierten Programmierung werden Zugriffsmodifikatoren verwendet, um die Sichtbarkeit und Zugänglichkeit von Klassenmitgliedern (Attributen und Methoden) zu steuern. Während viele Programmiersprachen strenge Zugriffsmodifikatoren wie public, private und protected haben, nimmt Python einen entspannteren Ansatz. Es folgt einer Philosophie, die oft als "Wir sind hier alle einverstanden" bezeichnet wird.
In Python gibt es drei Arten von Zugriffsmodifikatoren:
- Public
- Protected
- Private
Lassen Sie uns jede dieser Art mit Beispielen erkunden.
Öffentliche Mitglieder
In Python sind alle Mitglieder standardmäßig öffentlich. Das bedeutet, sie können von außerhalb der Klasse zugänglich sein. Hier ist ein Beispiel:
class Student:
def __init__(self, name, age):
self.name = name # Öffentliches Attribut
self.age = age # Öffentliches Attribut
def display_info(self): # Öffentliche Methode
print(f"Name: {self.name}, Age: {self.age}")
# Erstellen einer Instanz von Student
student1 = Student("Alice", 20)
# Zugriff auf öffentliche Mitglieder
print(student1.name) # Ausgabe: Alice
student1.display_info() # Ausgabe: Name: Alice, Age: 20
In diesem Beispiel sind name
, age
und display_info()
alle öffentlichen Mitglieder. Wir können auf sie direkt von außerhalb der Klasse zugreifen.
Geschützte Mitglieder
Geschützte Mitglieder werden durch das Präfix eines einzigen Unterstrichs (_ ) gekennzeichnet. Sie sind nicht wirklich privat und können noch von außerhalb der Klasse zugänglich sein, aber es ist eine Konvention, sie als interne Verwendung zu behandeln.
class Employee:
def __init__(self, name, salary):
self._name = name # Geschütztes Attribut
self._salary = salary # Geschütztes Attribut
def _display_salary(self): # Geschützte Methode
print(f"{self._name}'s Gehalt ist ${self._salary}")
# Erstellen einer Instanz von Employee
emp1 = Employee("Bob", 50000)
# Zugriff auf geschützte Mitglieder (Hinweis: Dies ist möglich, aber nicht empfohlen)
print(emp1._name) # Ausgabe: Bob
emp1._display_salary() # Ausgabe: Bob's Gehalt ist $50000
Während wir auf _name
, _salary
und _display_salary()
zugreifen können, wird allgemein nicht empfohlen, dies außerhalb der Klasse oder ihrer Unterklasse zu tun.
Private Mitglieder
Private Mitglieder werden durch das Präfix von doppelten Unterstrichen (__ ) gekennzeichnet. Python führt Namensverdrehung für diese Mitglieder durch, was ihren Zugriff von außerhalb der Klasse schwieriger (aber nicht unmöglich) macht.
class BankAccount:
def __init__(self, account_number, balance):
self.__account_number = account_number # Privates Attribut
self.__balance = balance # Privates Attribut
def __display_balance(self): # Private Methode
print(f"Kontostand: ${self.__balance}")
def public_display(self):
self.__display_balance()
# Erstellen einer Instanz von BankAccount
account1 = BankAccount("123456", 1000)
# Versuchen, private Mitglieder zu zugreifen
# print(account1.__account_number) # Dies wird eine AttributeError auslösen
# account1.__display_balance() # Dies wird auch eine AttributeError auslösen
# Zugriff auf private Methode über eine öffentliche Methode
account1.public_display() # Ausgabe: Kontostand: $1000
In diesem Beispiel sind __account_number
, __balance
und __display_balance()
private Mitglieder. Der Versuch, sie direkt von außerhalb der Klasse zu zugreifen, wird eine AttributeError auslösen.
Namensverdrehung
Erinnere dich, als ich erwähnte, dass private Mitglieder in Python nicht wirklich privat sind? Dies liegt an einem Mechanismus namens Namensverdrehung. Wenn du ein privates Mitglied mit doppelten Unterstrichen erstellst, ändert Python seinen Namen intern, um zu verhindern, dass man versehentlich darauf zugreift.
So funktioniert es:
class NameManglingDemo:
def __init__(self):
self.__private_var = "Ich bin privat!"
demo = NameManglingDemo()
print(dir(demo))
# Ausgabe: [..., '_NameManglingDemo__private_var', ...]
# Zugriff auf die private Variable mit dem verdrehten Namen
print(demo._NameManglingDemo__private_var) # Ausgabe: Ich bin privat!
Wie du siehst, benennt Python __private_var
in _NameManglingDemo__private_var
um. Dies ist die Namensverdrehung in Aktion!
Python-Eigenschaftsobjekt
Die property()
-Funktion in Python ist eine eingebaute Funktion, die ein Eigenschaftsobjekt erstellt und zurückgibt. Es ist eine Möglichkeit, Getter-, Setter- und Deleter-Methoden zu Klassenattributen hinzuzufügen.
Hier ist ein Beispiel:
class Temperature:
def __init__(self, celsius):
self._celsius = celsius
def get_fahrenheit(self):
return (self._celsius * 9/5) + 32
def set_fahrenheit(self, fahrenheit):
self._celsius = (fahrenheit - 32) * 5/9
fahrenheit = property(get_fahrenheit, set_fahrenheit)
# Verwendung der Eigenschaft
temp = Temperature(25)
print(temp.fahrenheit) # Ausgabe: 77.0
temp.fahrenheit = 86
print(temp._celsius) # Ausgabe: 30.0
In diesem Beispiel ist fahrenheit
eine Eigenschaft, die es ermöglicht, die Temperatur in Fahrenheit zu erhalten und zu setzen, während sie intern in Celsius gespeichert wird.
Getter- und Setter-Methoden
Getter- und Setter-Methoden sind Methoden, die verwendet werden, um die Werte von Klassenattributen zu erhalten und zu setzen. Sie bieten eine Möglichkeit, auf private Attribute zuzugreifen und diese zu modifizieren, während die Encapsulation aufrechterhalten wird.
Hier ist ein Beispiel mit dem @property
-Dekorator, der eine pythonischere Implementierung von Getter- und Setter-Methoden ist:
class Person:
def __init__(self, name, age):
self._name = name
self._age = age
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if not isinstance(value, str):
raise ValueError("Der Name muss eine Zeichenkette sein")
self._name = value
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int) or value < 0:
raise ValueError("Das Alter muss eine positive ganze Zahl sein")
self._age = value
# Verwendung von Getter- und Setter-Methoden
person = Person("Charlie", 30)
print(person.name) # Ausgabe: Charlie
person.name = "David"
print(person.name) # Ausgabe: David
try:
person.age = -5
except ValueError as e:
print(e) # Ausgabe: Das Alter muss eine positive ganze Zahl sein
In diesem Beispiel haben wir Getter- und Setter-Methoden für name
und age
erstellt. Die Setter-Methoden enthalten Validierungen, um sicherzustellen, dass die gesetzten Werte bestimmten Kriterien entsprechen.
Zusammenfassend hier die von uns besprochenen Methoden in Markdown-Format:
Methode | Beschreibung | Beispiel |
---|---|---|
Public | Von überall zugänglich | self.name |
Protected | Zugänglich innerhalb der Klasse und Unterklasse (nach Konvention) | self._name |
Private | Verdrehter Name zur Einschränkung des Zugriffs | self.__name |
Property | Erstellt ein Eigenschaftsobjekt | property(get_method, set_method) |
Getter | Methode zum Abrufen des Wertes eines Attributs | @property |
Setter | Methode zum Setzen des Wertes eines Attributs | @attribute.setter |
Und so ist es! Wir haben Zugriffsmodifikatoren in Python, Namensverdrehung, Eigenschaftsobjekte und Getter- und Setter-Methoden besprochen. Bedenke, dass Python's Ansatz zur Zugriffskontrolle mehr um Konventionen und Vertrauen als um strenge Regeln geht. Während du deinen Python-Weg weitergeht, wirst du finden, dass diese Flexibilität sauberen und lesbaren Code ermöglicht, während immer noch Möglichkeiten zur Implementierung von Encapsulation bestehen.
Weiter üben, neugierig bleiben und happy coding!
Credits: Image by storyset