Was bedeutet einfacher und doppelter Unterstrich vor einem Objektnamen?


1291

Kann jemand bitte die genaue Bedeutung von führenden Unterstrichen vor dem Namen eines Objekts in Python und den Unterschied zwischen beiden erklären?

Bleibt diese Bedeutung auch gleich, ob es sich bei dem fraglichen Objekt um eine Variable, eine Funktion, eine Methode usw. handelt?


2
Eine tolle kurze Antwort von einem anderen Thread: stackoverflow.com/a/8689983/911945
Anton Tarasenko

Antworten:


1155

Einzelner Unterstrich

Namen in einer Klasse mit einem führenden Unterstrich sollen anderen Programmierern lediglich anzeigen, dass das Attribut oder die Methode privat sein soll. Mit dem Namen selbst wird jedoch nichts Besonderes gemacht.

Um PEP-8 zu zitieren :

_single_leading_underscore: schwacher Indikator für den "internen Gebrauch". ZB from M import *importiert beispielsweise keine Objekte, deren Name mit einem Unterstrich beginnt.

Doppelter Unterstrich (Name Mangling)

Aus den Python-Dokumenten :

Jeder Bezeichner des Formulars __spam(mindestens zwei führende Unterstriche, höchstens ein nachfolgender Unterstrich) wird textuell durch ersetzt _classname__spam, wobei classnameder aktuelle Klassenname mit führenden Unterstrichen entfernt wird. Dieses Mangeln erfolgt ohne Rücksicht auf die syntaktische Position des Bezeichners, sodass damit klassenprivate Instanzen und Klassenvariablen, Methoden, in Globals gespeicherte Variablen und sogar in Instanzen gespeicherte Variablen definiert werden können. privat für diese Klasse bei Instanzen anderer Klassen.

Und eine Warnung von derselben Seite:

Das Mangeln von Namen soll Klassen eine einfache Möglichkeit bieten, "private" Instanzvariablen und -methoden zu definieren, ohne sich um Instanzvariablen kümmern zu müssen, die von abgeleiteten Klassen definiert werden, oder um Instanzvariablen durch Code außerhalb der Klasse zu mischen. Beachten Sie, dass die Mangling-Regeln hauptsächlich dazu dienen, Unfälle zu vermeiden. Es ist immer noch möglich, dass eine entschlossene Seele auf eine Variable zugreift oder diese ändert, die als privat betrachtet wird.

Beispiel

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

17
Was ist, wenn ein Variablenname mit 2 Unterstrichen deklariert ist, der nicht zur Klasse gehört? Es ist nur eine normale Variable, oder?
Dhruv Ramani

5
Was bedeutet ein __doppelter Unterstrich als Variablenname? wiea, __ = foo()
AJ

104
Diese Antwort ist äußerst irreführend, da der Leser glaubt, dass Dunderscore verwendet wird, um Instanzattribute "superprivat" zu machen. Dies ist nicht der Fall, wie hier von Raymond Hettinger erläutert , der ausdrücklich feststellt, dass Dunderscore fälschlicherweise verwendet wird, um Mitglieder als privat zu kennzeichnen, während es das Gegenteil von privat ist.
Markus Meskanen

13
@MarkusMeskanen Ich bin anderer Meinung, die Antwort besagt ausdrücklich die Verwendung eines Dunderscore, um Instanzen von klassenprivaten Variablen und Methoden zu erstellen. Während der Dunderscore so konzipiert wurde, dass diese Methoden und Variablen leicht von Unterklassen überschrieben (öffentlich gemacht) werden können, wird bei Verwendung eines Dunderscore eine private Instanz für die Verwendung innerhalb dieser Klasse beibehalten.
Arewm

6
@MarkusMeskanen: Es besteht die Freiheit, dass die Unterklassen dieselben Namen wie die Oberklasse verwenden, ohne die Oberklasse zu überlisten - mit anderen Worten, die Dunder-Namen der Oberklassen werden für sich selbst privat.
Ethan Furman

311

Bisher ausgezeichnete Antworten, aber einige Leckerbissen fehlen. Ein einzelner führender Unterstrich ist nicht gerade eine Konvention: Wenn Sie verwenden from foobar import *und das Modul foobarkeine __all__Liste definiert , enthalten die aus dem Modul importierten Namen keine Namen mit einem führenden Unterstrich. Nehmen wir an, es ist meistens eine Konvention, da dieser Fall eine ziemlich dunkle Ecke ist ;-).

Die Konvention zum führenden Unterstrich wird häufig nicht nur für private Namen verwendet, sondern auch für das, was C ++ als geschützte Namen bezeichnen würde - zum Beispiel für Namen von Methoden, die vollständig von Unterklassen überschrieben werden sollen (auch solche, die seitdem in überschrieben werden müssen Bei der Basisklasse handelt raise NotImplementedErrores sich häufig um Namen mit einem führenden Unterstrich, um dem Code mithilfe von Instanzen dieser Klasse (oder Unterklassen) anzuzeigen, dass diese Methoden nicht direkt aufgerufen werden sollen.

Um beispielsweise eine thread-sichere Warteschlange mit einer anderen Warteschlangendisziplin als FIFO zu erstellen, wird eine Warteschlange importiert, Queue.Queue in Unterklassen unterteilt und Methoden wie _getund überschrieben _put. "Client-Code" ruft niemals diese ("Hook") Methoden auf, sondern die ("organisierenden") öffentlichen Methoden wie putund get(dies wird als Entwurfsmuster für Vorlagenmethoden bezeichnet - siehe z. B. hier eine interessante Präsentation basierend auf einem Video von einem Vortrag von mir zu diesem Thema, mit Hinzufügung von Synopsen des Transkripts).

Bearbeiten: Die Videolinks in der Beschreibung der Vorträge sind jetzt defekt. Die ersten beiden Videos finden Sie hier und hier .


1
Wie entscheiden Sie, ob Sie + verwenden _var_nameoder var_name+ ausschließen möchten __all__?
Endolith

3
@endolith Verwenden Sie den führenden Unterstrich, um dem Leser Ihres Codes zu signalisieren, dass er diesen wahrscheinlich nicht verwenden sollte (z. B. weil Sie ihn möglicherweise in Version 2.0 oder sogar 1.1 ändern). Verwenden Sie explizit, __all__wann immer Sie das Modul benutzerfreundlich gestalten möchten from spam import *(auch beim interaktiven Interpreter). Die Antwort lautet also meistens beides .
Abarnert

@AlexMartelli Wird diese importbezogene Regel irgendwo in Dokumenten oder anderswo legal diskutiert?
Vicrobot

1
Ich mag die C ++ - Analogie. Erstens mag ich es nicht, wenn Leute das _ Private anrufen . Offensichtlich spreche ich von Analogien, da in Python nichts wirklich privat ist . Wenn wir in die Semantik eintauchen, würde ich sagen, dass wir das mit dem _von Java geschützten verknüpfen können, da in Java proctected "abgeleitete Klassen und / oder innerhalb desselben Pakets" bedeutet. Ersetzen Sie das Paket durch ein Modul, da PEP8 uns bereits mitteilt, dass dies _nicht nur eine Konvention ist, wenn es um *Importe geht, und Sie haben es. Und __wäre definitiv gleichbedeutend mit Javas privat, wenn es um Bezeichner innerhalb einer Klasse geht.
Marius Mucenicu

2
Es ist zwar eine anständige Antwort, aber auch eine starke Eigenwerbung.
Hybrid Web Dev

298

__foo__: Dies ist nur eine Konvention, eine Möglichkeit für das Python-System, Namen zu verwenden, die nicht mit Benutzernamen in Konflikt stehen.

_foo: Dies ist nur eine Konvention, mit der der Programmierer angeben kann, dass die Variable privat ist (was auch immer das in Python bedeutet).

__foo: Dies hat eine echte Bedeutung: Der Interpreter ersetzt diesen Namen durch _classname__foo, um sicherzustellen, dass sich der Name nicht mit einem ähnlichen Namen in einer anderen Klasse überschneidet.

Keine andere Form von Unterstrichen hat in der Python-Welt eine Bedeutung.

In diesen Konventionen gibt es keinen Unterschied zwischen Klasse, Variable, Global usw.


6
Bin gerade rübergekommen __foound neugierig. Wie kann es sich mit ähnlichen Methodennamen mit anderen Klassen überschneiden? Ich meine, Sie müssen immer noch darauf zugreifen instance.__foo()(wenn es nicht vom Dolmetscher umbenannt wurde), oder?
Bibhas Debnath

81
Dieser Typ gibt an, dass from module import *keine Objekte mit Unterstrichen importiert werden. Daher _fooist mehr als nur eine Konvention.
Dotancohen

4
@Bibhas: Wenn die Klasse die BUnterklassen der Klasse Aist und beide implementieren foo(), wird B.foo()die .foo()geerbte Klasse überschrieben A. Eine Instanz von Bkann nur auf zugreifen B.foo(), außer über super(B).foo().
naught101

3
Bei __dunder__Namen überspringen implizite Aufrufe das Instanzwörterbuch , sodass es in einigen Fällen möglicherweise mehr als nur eine Namenskonvention ist (siehe Abschnitt zur Suche nach speziellen Methoden im Datenmodell).
wim

206

._variable ist halbprivat und nur für Konventionen gedacht

.__variablewird oft fälschlicherweise als überprivat angesehen, während es eigentlich nur darum geht, Namen zu bündeln, um einen versehentlichen Zugriff zu verhindern [1].

.__variable__ ist normalerweise für integrierte Methoden oder Variablen reserviert

Sie können weiterhin auf .__mangledVariablen zugreifen , wenn Sie dies unbedingt möchten. Das Doppel unterstreicht nur das Benennen oder Umbenennen der Variablen in etwas wieinstance._className__mangled

Beispiel:

class Test(object):
    def __init__(self):
        self.__a = 'a'
        self._b = 'b'

>>> t = Test()
>>> t._b
'b'

Auf t._b kann zugegriffen werden, da es nur durch Konventionen verborgen ist

>>> t.__a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'Test' object has no attribute '__a'

t .__ a wird nicht gefunden, da es aufgrund von Namensveränderungen nicht mehr existiert

>>> t._Test__a
'a'

Durch Zugriff instance._className__variableauf nur den doppelten Unterstrich können Sie auf den versteckten Wert zugreifen


Aber wie wäre es, wenn "__a" eine Klassenvariable wäre, dann könnten Sie nicht einmal mit den Anweisungen aus Python-Dokumenten darauf
zugreifen

Können Sie Ihre Antwort mit einem Beispiel für einen doppelten Unterstrich in Bezug auf die Vererbung aktualisieren?
Variable

116

Einzelner Unterstrich am Anfang:

Python hat keine echten privaten Methoden. Stattdessen bedeutet ein Unterstrich am Anfang eines Methoden- oder Attributnamens, dass Sie nicht auf diese Methode zugreifen sollten, da sie nicht Teil der API ist.

class BaseForm(StrAndUnicode):

    def _get_errors(self):
        "Returns an ErrorDict for the data provided for the form"
        if self._errors is None:
            self.full_clean()
        return self._errors

    errors = property(_get_errors)

(Dieses Code-Snippet wurde aus dem Django-Quellcode entnommen: django / forms / forms.py). In diesem Code errorshandelt es sich um eine öffentliche Eigenschaft, aber die von dieser Eigenschaft aufgerufene Methode _get_errors ist "privat", sodass Sie nicht darauf zugreifen sollten.

Zwei Unterstriche am Anfang:

Dies führt zu großer Verwirrung. Es sollte nicht zum Erstellen einer privaten Methode verwendet werden. Es sollte verwendet werden, um zu vermeiden, dass Ihre Methode von einer Unterklasse überschrieben wird oder versehentlich darauf zugegriffen wird. Sehen wir uns ein Beispiel an:

class A(object):
    def __test(self):
        print "I'm a test method in class A"

    def test(self):
        self.__test()

a = A()
a.test()
# a.__test() # This fails with an AttributeError
a._A__test() # Works! We can access the mangled name directly!

Ausgabe:

$ python test.py
I'm test method in class A
I'm test method in class A

Erstellen Sie nun eine Unterklasse B und passen Sie die __test-Methode an

class B(A):
    def __test(self):
        print "I'm test method in class B"

b = B()
b.test()

Ausgabe wird sein ....

$ python test.py
I'm test method in class A

Wie wir gesehen haben, hat A.test () nicht wie erwartet die Methoden B .__ test () aufgerufen. Tatsächlich ist dies jedoch das richtige Verhalten für __. Die beiden Methoden mit dem Namen __test () werden automatisch in _A__test () und _B__test () umbenannt (entstellt), sodass sie nicht versehentlich überschrieben werden. Wenn Sie eine Methode erstellen, die mit __ beginnt, bedeutet dies, dass Sie nicht möchten, dass jemand sie überschreiben kann, und dass Sie nur innerhalb der eigenen Klasse darauf zugreifen möchten.

Zwei Unterstriche am Anfang und am Ende:

Wenn wir eine Methode wie sehen __this__, rufen Sie sie nicht auf. Dies ist eine Methode, die Python aufrufen soll, nicht Sie. Lass uns mal sehen:

>>> name = "test string"
>>> name.__len__()
11
>>> len(name)
11

>>> number = 10
>>> number.__add__(40)
50
>>> number + 50
60

Es gibt immer einen Operator oder eine native Funktion, die diese magischen Methoden aufruft. Manchmal ist es nur ein Hook, den Python in bestimmten Situationen aufruft. Wird zum Beispiel __init__()aufgerufen, wenn das Objekt erstellt wird, nachdem __new__()aufgerufen wurde, um die Instanz zu erstellen ...

Nehmen wir ein Beispiel ...

class FalseCalculator(object):

    def __init__(self, number):
        self.number = number

    def __add__(self, number):
        return self.number - number

    def __sub__(self, number):
        return self.number + number

number = FalseCalculator(20)
print number + 10      # 10
print number - 20      # 40

Weitere Informationen finden Sie im PEP-8-Handbuch . Weitere magische Methoden finden Sie in diesem PDF .


1
Nachdem ich diese Antwort selbst bearbeitet habe, bevorzuge ich stackoverflow.com/a/8689983/1048186
Josiah Yoder

Was meinen Sie mit "Wie wir gesehen haben, hat A.test () keine B .__ test () -Methoden aufgerufen" - wo haben Sie A.test () aufgerufen?
variabel

18

Manchmal haben Sie ein Tupel mit einem führenden Unterstrich wie in

def foo(bar):
    return _('my_' + bar)

In diesem Fall ist _ () ein Alias ​​für eine Lokalisierungsfunktion, die Text verarbeitet, um ihn basierend auf dem Gebietsschema in die richtige Sprache usw. zu bringen. Zum Beispiel macht Sphinx dies und Sie finden unter den Importen

from sphinx.locale import l_, _

und in sphinx.locale wird _ () als Alias ​​einer Lokalisierungsfunktion zugewiesen.


11

Da beziehen sich so viele Leute auf Raymond's Vortrag , werde ich es nur ein wenig einfacher machen, indem ich aufschreibe, was er gesagt hat:

Bei der Absicht der doppelten Unterstriche ging es nicht um Privatsphäre. Die Absicht war, es genau so zu verwenden

class Circle(object):

    def __init__(self, radius):
        self.radius = radius

    def area(self):
        p = self.__perimeter()
        r = p / math.pi / 2.0
        return math.pi * r ** 2.0

    def perimeter(self):
        return 2.0 * math.pi * self.radius

    __perimeter = perimeter  # local reference


class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

Es ist eigentlich das Gegenteil von Privatsphäre, es geht nur um Freiheit. Dadurch können Ihre Unterklassen eine Methode überschreiben, ohne die anderen zu beschädigen .

Angenommen, Sie behalten keine lokale Referenz von perimeterin Circle. Jetzt Tireüberschreibt eine abgeleitete Klasse die Implementierung von perimeter, ohne sie zu berühren area. Wenn Sie anrufen Tire(5).area(), sollte es theoretisch immer noch Circle.perimeterzur Berechnung verwendet werden, aber in Wirklichkeit wird es verwendet Tire.perimeter, was nicht das beabsichtigte Verhalten ist. Deshalb brauchen wir eine lokale Referenz in Circle.

Aber warum __perimeterstatt _perimeter? weil_perimeter abgeleitete Klassen immer noch die Möglichkeit haben, Folgendes zu überschreiben:

class Tire(Circle):

    def perimeter(self):
        return Circle.perimeter(self) * 1.25

    _perimeter = perimeter

Doppelte Unterstriche haben Namensverknüpfungen, daher besteht nur eine sehr geringe Wahrscheinlichkeit, dass die lokale Referenz in der übergeordneten Klasse in der abgeleiteten Klasse überschrieben wird. also " Ihre Unterklassen eine Methode überschreiben, ohne die anderen zu beschädigen ".

Wenn Ihre Klasse nicht vererbt wird oder das Überschreiben von Methoden nichts kaputt macht, brauchen Sie es einfach nicht __double_leading_underscore.


1
Vielen Dank, die Folie wurde nicht richtig angezeigt, sodass ich nicht untersucht habe, warum mein Code fehlschlagen würde.
cgte

8

Wenn man eine Variable wirklich schreibgeschützt machen möchte, ist IMHO der beste Weg, property () zu verwenden, an die nur ein Getter übergeben wird. Mit property () können wir die Daten vollständig kontrollieren.

class PrivateVarC(object):

    def get_x(self):
        pass

    def set_x(self, val):
        pass

    rwvar = property(get_p, set_p)  

    ronly = property(get_p) 

Ich verstehe, dass OP eine etwas andere Frage gestellt hat, aber da ich eine andere Frage gefunden habe, in der gefragt wurde, wie private Variablen gesetzt werden sollen, habe ich mir überlegt, diese zusätzlichen Informationen hier hinzuzufügen.


8

Zu https://dbader.org/blog/meaning-of-underscores-in-python

  • Einzelner führender Unterstrich (_var) : Die Namenskonvention, die einen Namen angibt, ist für den internen Gebrauch bestimmt. Im Allgemeinen nicht vom Python-Interpreter erzwungen (außer bei Platzhalterimporten) und nur als Hinweis für den Programmierer gedacht.
  • Single Trailing Underscore (var_) : Wird von der Konvention verwendet, um Namenskonflikte mit Python-Schlüsselwörtern zu vermeiden.
  • Double Leading Underscore (__ var) : Löst die Namensverfälschung aus, wenn sie in einem Klassenkontext verwendet wird. Erzwungen durch den Python-Interpreter.
  • Doppelter führender und nachfolgender Unterstrich (__ var__) : Gibt spezielle Methoden an, die von der Python-Sprache definiert werden. Vermeiden Sie dieses Namensschema für Ihre eigenen Attribute.
  • Einzelner Unterstrich (_) : Wird manchmal als Name für temporäre oder unbedeutende Variablen verwendet („egal“). Außerdem: Das Ergebnis des letzten Ausdrucks in einer Python-REPL.

5

Tolle Antworten und alle sind richtig. Ich habe ein einfaches Beispiel zusammen mit einer einfachen Definition / Bedeutung geliefert.

Bedeutung:

some_variable --► es ist öffentlich, dass jeder dies sehen kann.

_some_variable --► es ist öffentlich, jeder kann dies sehen, aber es ist eine Konvention, um privat anzuzeigen ... Warnung, dass Python keine Durchsetzung durchführt.

__some_varaible --► Python ersetzt den Variablennamen durch _classname__some_varaible (AKA name mangling) und reduziert / verbirgt die Sichtbarkeit und ähnelt eher einer privaten Variablen.

Nur um ehrlich zu sein Laut Python-Dokumentation

"" Private "Instanzvariablen, auf die nur innerhalb eines Objekts zugegriffen werden kann, sind in Python nicht vorhanden."

Das Beispiel:

class A():
    here="abc"
    _here="_abc"
    __here="__abc"


aObject=A()
print(aObject.here) 
print(aObject._here)
# now if we try to print __here then it will fail because it's not public variable 
#print(aObject.__here)

_ _some_varaible - .... und es reduziert / verbirgt seine Sichtbarkeit und ähnelt eher einer privaten Variablen. Nein, Name Mangling ist der Punkt, es verbirgt die Methode nicht.
AMC

4

Einzelne führende Unterstriche sind eine Konvention. Aus Sicht des Dolmetschers gibt es keinen Unterschied, ob Namen mit einem einzelnen Unterstrich beginnen oder nicht.

Doppel Vorder- und Hinter Unterstrichen werden verwendet für integrierte Methoden, wie zum Beispiel __init__, __bool__usw.

Doppelte führende Unterstriche ohne nachfolgende Gegenstücke sind ebenfalls eine Konvention, jedoch werden die Klassenmethoden vom Interpreter entstellt . Für Variablen oder grundlegende Funktionsnamen besteht kein Unterschied.


3

Ihre Frage ist gut, es geht nicht nur um Methoden. Funktionen und Objekten in Modulen wird normalerweise auch ein Unterstrich vorangestellt, und zwei können vorangestellt werden.

Aber __double_underscore-Namen werden beispielsweise in Modulen nicht namentlich entstellt. Was passiert ist, dass Namen, die mit einem (oder mehreren) Unterstrichen beginnen, nicht importiert werden, wenn Sie alle aus einem Modul importieren (aus Modulimport *), noch werden die Namen in der Hilfe (Modul) angezeigt.


1
Darüber hinaus verhalten sich Namen, die mit einem oder mehreren Unterstrichen beginnen, die zwei oder mehr nachfolgende Unterstriche haben, wieder wie alle anderen Namen.
Bentley4

3

Hier ist ein einfaches veranschaulichendes Beispiel dafür, wie sich doppelte Unterstricheigenschaften auf eine geerbte Klasse auswirken können. Also mit folgendem Setup:

class parent(object):
    __default = "parent"
    def __init__(self, name=None):
        self.default = name or self.__default

    @property
    def default(self):
        return self.__default

    @default.setter
    def default(self, value):
        self.__default = value


class child(parent):
    __default = "child"

Wenn Sie dann eine untergeordnete Instanz in der Python-REPL erstellen, wird Folgendes angezeigt

child_a = child()
child_a.default            # 'parent'
child_a._child__default    # 'child'
child_a._parent__default   # 'parent'

child_b = child("orphan")
## this will show 
child_b.default            # 'orphan'
child_a._child__default    # 'child'
child_a._parent__default   # 'orphan'

Für manche mag dies offensichtlich sein, aber es hat mich in einer viel komplexeren Umgebung überrascht


3

In Python gibt es keine "privaten" Instanzvariablen, auf die nur innerhalb eines Objekts zugegriffen werden kann. Es gibt jedoch eine Konvention, die von den meisten Python-Codes befolgt wird: Ein Name mit einem Unterstrich (z. B. _spam) sollte als nicht öffentlicher Teil der API behandelt werden (unabhängig davon, ob es sich um eine Funktion, eine Methode oder ein Datenelement handelt). . Es sollte als Implementierungsdetail betrachtet werden und kann ohne vorherige Ankündigung geändert werden.

Referenz https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references


1
_ ist zum Beispiel intern in c # viel ähnlicher als privat. Doppelter Unterstrich ist dem privaten viel ähnlicher als dem privaten, würde ich sagen.
Ini

2

Es ist ziemlich einfach, die Fakten von _ und __ zu erfahren. Die anderen Antworten drücken sie ziemlich gut aus. Die Verwendung ist viel schwieriger zu bestimmen.

So sehe ich das:

_

Sollte verwendet werden, um anzuzeigen, dass eine Funktion nicht für den öffentlichen Gebrauch bestimmt ist, wie beispielsweise eine API. Dies und die Importbeschränkung bewirken, dass es sich ähnlich wie internalin c # verhält .

__

Sollte verwendet werden, um eine Namenskollision in der Erbhirarchie zu vermeiden und um eine spätere Bindung zu vermeiden. Ähnlich wie privat in c #.

==>

Wenn Sie angeben möchten, dass etwas nicht für den öffentlichen Gebrauch bestimmt ist, sich aber wie ein protectedGebrauch verhalten sollte _. Wenn Sie angeben möchten, dass etwas nicht für den öffentlichen Gebrauch bestimmt ist, sich aber wie ein privateGebrauch verhalten sollte __.

Dies ist auch ein Zitat, das mir sehr gefällt:

Das Problem ist, dass der Autor einer Klasse zu Recht der Meinung ist, dass "dieser Attribut- / Methodenname privat sein sollte und nur innerhalb dieser Klassendefinition zugänglich ist" und die __private-Konvention verwendet. Später kann ein Benutzer dieser Klasse jedoch eine Unterklasse erstellen, die zu Recht Zugriff auf diesen Namen benötigt. Entweder muss die Oberklasse geändert werden (was schwierig oder unmöglich sein kann), oder der Unterklassencode muss manuell entstellte Namen verwenden (was bestenfalls hässlich und fragil ist).

Das Problem dabei ist jedoch meiner Meinung nach, dass es eine Weile dauern kann, den Fehler zu finden, wenn es keine IDE gibt, die Sie beim Überschreiben von Methoden warnt, wenn Sie versehentlich eine Methode aus einer Basisklasse überschrieben haben.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.