Wenn Sie Zweifel haben, lassen Sie es "öffentlich" - ich meine, fügen Sie nichts hinzu, um den Namen Ihres Attributs zu verschleiern. Wenn Sie eine Klasse mit einem internen Wert haben, kümmern Sie sich nicht darum. Anstatt zu schreiben:
class Stack(object):
def __init__(self):
self.__storage = [] # Too uptight
def push(self, value):
self.__storage.append(value)
schreibe dies standardmäßig:
class Stack(object):
def __init__(self):
self.storage = [] # No mangling
def push(self, value):
self.storage.append(value)
Dies ist mit Sicherheit eine kontroverse Vorgehensweise. Python-Neulinge hassen es einfach und sogar einige alte Python-Leute verachten diese Standardeinstellung - aber es ist trotzdem die Standardeinstellung. Ich empfehle Ihnen daher, sie zu befolgen, auch wenn Sie sich unwohl fühlen.
Wenn Sie wirklich die Nachricht "Kann dies nicht berühren!" Senden möchten Für Ihre Benutzer besteht die übliche Methode darin, der Variablen einen Unterstrich voranzustellen. Dies ist nur eine Konvention, aber die Leute verstehen sie und gehen beim Umgang mit solchen Dingen doppelt vorsichtig vor:
class Stack(object):
def __init__(self):
self._storage = [] # This is ok but pythonistas use it to be relaxed about it
def push(self, value):
self._storage.append(value)
Dies kann auch nützlich sein, um Konflikte zwischen Eigenschaftsnamen und Attributnamen zu vermeiden:
class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0
@property
def age(self):
return self._age
@age.setter
def age(self, age):
if age >= 0:
self._age = age
else:
self._age = 0
Was ist mit dem doppelten Unterstrich? Nun, die Magie des doppelten Unterstrichs wird hauptsächlich verwendet , um ein versehentliches Überladen von Methoden und Namenskonflikten mit den Attributen von Oberklassen zu vermeiden . Es kann sehr nützlich sein, wenn Sie eine Klasse schreiben, von der erwartet wird, dass sie um ein Vielfaches erweitert wird.
Wenn Sie es für andere Zwecke verwenden möchten, können Sie dies, aber es ist weder üblich noch empfohlen.
BEARBEITEN : Warum ist das so? Nun, der übliche Python-Stil betont nicht, Dinge privat zu machen - im Gegenteil! Dafür gibt es viele Gründe - die meisten sind umstritten ... Lassen Sie uns einige davon sehen.
Python hat Eigenschaften
Die meisten OO-Sprachen verwenden heutzutage den umgekehrten Ansatz: Was nicht verwendet werden sollte, sollte nicht sichtbar sein, daher sollten Attribute privat sein. Theoretisch würde dies zu besser verwaltbaren, weniger gekoppelten Klassen führen, da niemand die Werte innerhalb der Objekte rücksichtslos ändern würde.
Es ist jedoch nicht so einfach. Zum Beispiel Java - Klassen haben eine Menge Attribute haben und Getter , die nur bekommen die Werte und Setter , die gerade gesetzt , die Werte. Sie benötigen beispielsweise sieben Codezeilen, um ein einzelnes Attribut zu deklarieren - was ein Python-Programmierer als unnötig komplex bezeichnen würde. In der Praxis schreiben Sie einfach diese ganze Menge Code, um ein öffentliches Feld zu erhalten, da Sie den Wert mithilfe der Getter und Setter ändern können.
Warum sollten Sie diese standardmäßig private Richtlinie befolgen? Machen Sie Ihre Attribute einfach standardmäßig öffentlich. Dies ist in Java natürlich problematisch, da Sie alle Änderungen vornehmen müssen, wenn Sie Ihrem Attribut eine Validierung hinzufügen möchten
person.age = age;
in Ihrem Code zu, lassen Sie uns sagen,
person.setAge(age);
setAge()
Sein:
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
this.age = 0;
}
}
In Java (und anderen Sprachen) werden standardmäßig Getter und Setter verwendet, da das Schreiben lästig sein kann, Sie jedoch viel Zeit sparen können, wenn Sie sich in der von mir beschriebenen Situation befinden.
Sie müssen dies jedoch nicht in Python tun, da Python Eigenschaften hat. Wenn Sie diese Klasse haben:
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
Wenn Sie sich entscheiden, das Alter zu überprüfen, müssen Sie die person.age = age
Teile Ihres Codes nicht ändern . Fügen Sie einfach eine Eigenschaft hinzu (wie unten gezeigt)
class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0
@property
def age(self):
return self._age
@age.setter
def age(self, age):
if age >= 0:
self._age = age
else:
self._age = 0
Wenn Sie dies tun und trotzdem verwenden können person.age = age
, warum sollten Sie dann private Felder sowie Getter und Setter hinzufügen?
(Siehe auch Python ist nicht Java und dieser Artikel über die Nachteile der Verwendung von Gettern und Setzern .)
Alles ist sowieso sichtbar - und der Versuch, sich zu verstecken, erschwert Ihre Arbeit
Selbst in Sprachen, in denen private Attribute vorhanden sind, können Sie über eine Art Reflexions- / Selbstbeobachtungsbibliothek darauf zugreifen. Und die Leute tun es oft, in Rahmenbedingungen und zur Lösung dringender Bedürfnisse. Das Problem ist, dass Introspektionsbibliotheken nur eine schwierige Methode sind, um das zu tun, was Sie mit öffentlichen Attributen tun können.
Da Python eine sehr dynamische Sprache ist, ist es nur kontraproduktiv, diese Belastung Ihren Klassen hinzuzufügen.
Das Problem ist nicht erkennbar - es ist erforderlich gesehen werden
Für einen Pythonista ist die Kapselung nicht die Unfähigkeit, die Interna von Klassen zu sehen, sondern die Möglichkeit, das Betrachten zu vermeiden. Ich meine, Kapselung ist die Eigenschaft einer Komponente, die es ermöglicht, sie zu verwenden, ohne dass sich der Benutzer um die internen Details kümmert. Wenn Sie eine Komponente verwenden können, ohne sich um ihre Implementierung zu kümmern, ist sie gekapselt (nach Meinung eines Python-Programmierers).
Wenn Sie Ihre Klasse so geschrieben haben, dass Sie sie verwenden können, ohne über Implementierungsdetails nachdenken zu müssen, gibt es kein Problem, wenn Sie aus irgendeinem Grund in die Klasse schauen möchten . Der Punkt ist: Ihre API sollte gut sein und der Rest sind Details.
Guido sagte es
Nun, das ist nicht umstritten: Er sagte es tatsächlich . (Suchen Sie nach "offenem Kimono".)
Das ist Kultur
Ja, es gibt einige Gründe, aber keinen kritischen Grund. Dies ist hauptsächlich ein kultureller Aspekt der Programmierung in Python. Ehrlich gesagt könnte es auch umgekehrt sein - ist es aber nicht. Sie können auch genauso gut umgekehrt fragen: Warum verwenden einige Sprachen standardmäßig private Attribute? Aus dem gleichen Hauptgrund wie für die Python-Praxis: Weil es die Kultur dieser Sprachen ist und jede Wahl Vor- und Nachteile hat.
Da es diese Kultur bereits gibt, sind Sie gut beraten, ihr zu folgen. Andernfalls ärgern Sie sich über Python-Programmierer, die Sie auffordern, das __
aus Ihrem Code zu entfernen , wenn Sie eine Frage in Stack Overflow stellen :)