Wenn "explizit ist besser als implizit", warum gibt es in Python keine expliziten Zugriffsmodifikatoren: öffentlich, geschützt, privat usw.?
Ich weiß, dass die Idee ist, dass der Programmierer durch einen Hinweis wissen sollte, was zu tun ist - keine Notwendigkeit, "rohe Gewalt" anzuwenden. Aber IMO 'Encapsulation' oder 'Information Hiding' soll nicht nur Menschen fernhalten, sondern ist auch eine Frage der Organisation und Struktur: Ihre Entwicklungsebenen sollten selbstdefinierende, klar abgegrenzte Bereiche und Grenzen haben, genau wie physische Systeme.
Kann mir hier bitte jemand mit einer soliden Erklärung helfen, warum Zugriffsbeschränkungen in Python, einer Sprache, die ansonsten nahezu perfekt zu sein scheint, eher impliziert als explizit sind?
Bearbeiten: Bisher habe ich 3 vorgeschlagene Antworten gesehen und festgestellt, dass meine Frage aus 2 Teilen besteht:
Warum gibt es zum Beispiel keine Schlüsselwörter?
private def myFunc(): dostuff....
statt IMO die hässlichen und schwer zu tippenden Unterstriche. Aber das ist nicht der wichtige Punkt.
Wichtiger:
Warum werden diese Zugriffsmodifikatoren nur "Empfehlungen" oder Hinweise und nicht erzwungen. Es wird schwer sein, später zu ändern? Es ist sehr einfach, "geschützt" in "öffentlich" zu ändern - und wenn Sie eine komplizierte Vererbungskette haben, die es schwierig macht, haben Sie ein schlechtes Design - Ihr Design sollte verfeinert werden, anstatt sich auf eine Sprachfunktion zu verlassen, die das Schreiben erleichtert schlecht strukturierter Code.
Wenn Zugriffsmodifikatoren erzwungen werden, wird Ihr Code automatisch unterteilt. Sie wissen, dass bestimmte Segmente außerhalb des Gültigkeitsbereichs liegen, sodass Sie sich nur dann mit ihnen befassen müssen, wenn dies erforderlich ist. Und wenn Ihr Design nicht gut ist und Sie ständig Dinge in verschiedene Bereiche verschieben oder aus diesen entfernen, kann Ihnen die Sprache dabei helfen, Ihren Akt zu bereinigen.
So sehr ich Python liebe, finde ich, dass dieser zweite Punkt ein schwerwiegender Mangel ist. Und ich habe noch keine gute Antwort darauf.
quelle
private def whatever
ist, dass diesclass x: def whatever(self): pass
eine Abkürzung istclass x: pass; x.whatever = lambda self: pass
, weshalb Sie im Grunde genommen einen privaten Modifikator für die Zuweisung benötigen würdenAntworten:
"Explizit ist besser als implizit" ist nur eine der Maximen in Pythons Designphilosophie. "Einfach ist besser als komplex" gibt es auch. Und obwohl es nicht im Zen von Python steht, ist "Wir stimmen alle Erwachsenen hier zu" eine andere.
Diese zweite Regel ist hier vielleicht die wichtigste. Wenn ich eine Klasse entwerfe, habe ich eine Vorstellung davon, wie sie verwendet werden soll. Aber ich kann unmöglich alle möglichen Verwendungen vorhersagen. Es kann sein, dass eine zukünftige Verwendung meines Codes den Zugriff auf die Variablen erfordert, die ich als privat angesehen habe. Warum sollte ich es mir schwer machen - oder sogar unmöglich - darauf zuzugreifen, wenn ein zukünftiger Programmierer (oder sogar ein zukünftiges Ich) sie benötigt? Am besten kennzeichnen Sie sie mit einer Warnung - wie Joonas bemerkt, ist ein einzelner Unterstrich das Standardpräfix -, dass sie intern sind und sich möglicherweise ändern. es erscheint jedoch unnötig, den Zugang insgesamt zu verbieten.
quelle
Ich würde vermuten, dass der Hauptgrund für die fehlenden Zugriffsmodifikatoren die Einfachheit ist
Wie Sie sagen, es geht nicht darum, Menschen fernzuhalten, sondern um Organisation. Der Hauptaspekt von "privat" ist, dass es eine Nachricht an die Benutzer Ihrer API sendet. Schreiben Sie bitte keinen Code, der davon abhängt.
Es ist trivial zu sagen, dass _x oder __x nicht außerhalb der Klasse verwendet werden sollten, aber in Pythons dynamischem Objektmodell ist es schwierig, überhaupt eine Notation zu finden.
Wie kann man die Zugänglichkeit feststellen?
Ich denke, das war ein Kompromiss. Wenn Sie strikt nicht damit leben können, würde ich Ruby vorschlagen, das eine ähnliche Abstraktion und Dynamik aufweist, aber ein Objektmodell, das Zugriffsmodifikationen ermöglicht.
quelle
__x__
„magisch“ (dh Methoden, die aufgerufen werden, um die Sprachintegration zu ermöglichen, z. B. Überladen von Operatoren, Iterierbarkeit usw.). Die Konvention ist_x
.__init__
war zufällig. In diesem Beispiel werden einige Eigenschaften des Objekts festgelegt, die zum Zeitpunkt der Kompilierung nicht bekannt sind, sodass ein expliziter Zugriffsmodifikator nicht hilfreich ist.Die Python-Konvention sieht die Verwendung eines Unterstrich-Präfixes für geschützte / private Mitglieder vor.
Wenn diese Konvention befolgt wird, ist sie praktisch mit den Zugriffsmodifikatoren identisch, mit der Ausnahme, dass 1) Sie direkt am Namen des Mitglieds erkennen, ob er öffentlich ist oder nicht, und 2) Sie die "Kapselung" aufheben können , wenn Sie dies wirklich möchten (dies kann gerechtfertigt sein) in zB testing; in einigen anderen sprachen müssten sie reflection == more code verwenden).
Letztendlich ist es eine Frage des Geschmacks, aber wenn Sie dasselbe (mit etwas mehr Flexibilität) ohne spezielle Schlüsselwörter tun können, wird die Sprache kleiner und der Code wird prägnanter, was im Allgemeinen eine gute Sache ist.
quelle