Python hat kein Datenschutzmodell, es gibt keine Zugriffsmodifikatoren wie in C ++, C # oder Java. Es gibt keine wirklich "geschützten" oder "privaten" Attribute.
Namen mit einem führenden doppelten Unterstrich und keinem nachfolgenden doppelten Unterstrich werden entstellt , um sie bei der Vererbung vor Zusammenstößen zu schützen. Unterklassen können ihre eigene __private()
Methode definieren , und diese stören nicht den gleichen Namen in der übergeordneten Klasse. Solche Namen gelten als klassenprivat ; Sie sind immer noch von außerhalb der Klasse zugänglich, aber es ist weitaus weniger wahrscheinlich, dass sie versehentlich zusammenstoßen.
Mangling wird durchgeführt, indem einem solchen Namen ein zusätzlicher Unterstrich und der Klassenname vorangestellt werden (unabhängig davon, wie der Name verwendet wird oder ob er existiert), wodurch ihnen effektiv ein Namespace zugewiesen wird . In der Parent
Klasse wird jeder __private
Bezeichner (zur Kompilierungszeit) durch den Namen ersetzt _Parent__private
, während in der Child
Klasse der Bezeichner _Child__private
überall in der Klassendefinition durch ersetzt wird .
Folgendes wird funktionieren:
class Child(Parent):
def foo(self):
self._protected()
def bar(self):
self._Parent__private()
Siehe Reservierte Klassen von Bezeichnern in der Dokumentation zur lexikalischen Analyse:
__*
Klassenprivate Namen. Namen in dieser Kategorie werden, wenn sie im Kontext einer Klassendefinition verwendet werden, neu geschrieben, um ein verstümmeltes Formular zu verwenden, um Namenskonflikte zwischen „privaten“ Attributen von Basisklassen und abgeleiteten Klassen zu vermeiden.
und die referenzierte Dokumentation zu Namen :
Mangeln von privaten Namen : Wenn ein Bezeichner, der in einer Klassendefinition in Textform vorkommt, mit zwei oder mehr Unterstrichen beginnt und nicht mit zwei oder mehr Unterstrichen endet, wird er als privater Name dieser Klasse betrachtet. Private Namen werden in eine längere Form umgewandelt, bevor Code für sie generiert wird. Bei der Umwandlung wird der Klassenname eingefügt, wobei führende Unterstriche entfernt und ein einzelner Unterstrich vor dem Namen eingefügt wird. Beispielsweise wird der __spam
in einer Klasse mit dem Namen Ham vorkommende Bezeichner in transformiert _Ham__spam
. Diese Transformation ist unabhängig vom syntaktischen Kontext, in dem der Bezeichner verwendet wird.
Verwenden Sie keine klassenprivaten Namen, es sei denn, Sie möchten Entwicklern, die Ihre Klasse unterordnen möchten, ausdrücklich mitteilen, dass sie bestimmte Namen nicht verwenden können oder das Risiko eingehen, Ihre Klasse zu beschädigen. Außerhalb veröffentlichter Frameworks und Bibliotheken wird diese Funktion kaum verwendet.
Der PEP 8 Python Style Guide enthält Folgendes zum Mangeln von privaten Namen:
Wenn Ihre Klasse als Unterklasse gedacht ist und Sie Attribute haben, die keine Unterklassen verwenden sollen, sollten Sie sie mit doppelt führenden Unterstrichen und keinen nachfolgenden Unterstrichen benennen. Dies ruft den Namensveränderungsalgorithmus von Python auf, bei dem der Name der Klasse in den Attributnamen entstellt wird. Dies hilft, Kollisionen von Attributnamen zu vermeiden, falls Unterklassen versehentlich Attribute mit demselben Namen enthalten.
Hinweis 1: Beachten Sie, dass im verstümmelten Namen nur der einfache Klassenname verwendet wird. Wenn also eine Unterklasse denselben Klassennamen und denselben Attributnamen auswählt, können Sie dennoch Namenskollisionen erhalten.
Hinweis 2: Das Mangeln von Namen kann bestimmte Verwendungszwecke haben, z. B. das Debuggen und
__getattr__()
ist weniger bequem. Der Name Mangling-Algorithmus ist jedoch gut dokumentiert und einfach manuell durchzuführen.
Anmerkung 3: Nicht jeder mag das Mangeln von Namen. Versuchen Sie, die Notwendigkeit, versehentliche Namenskonflikte zu vermeiden, mit der potenziellen Verwendung durch fortgeschrittene Anrufer in Einklang zu bringen.