Python Name Mangling

108

In anderen Sprachen ist eine allgemeine Richtlinie, die zur Erstellung von besserem Code beiträgt, immer, alles so versteckt wie möglich zu machen. Wenn Sie sich nicht sicher sind, ob eine Variable privat oder geschützt sein soll, sollten Sie sich für privat entscheiden.

Gilt das auch für Python? Sollte ich zuerst zwei führende Unterstriche für alles verwenden und sie nur weniger versteckt machen (nur einen Unterstrich), wenn ich sie brauche?

Wenn die Konvention nur einen Unterstrich verwenden soll, würde ich auch gerne die Gründe kennen.

Hier ist ein Kommentar, den ich zu JBernardos Antwort hinterlassen habe . Es erklärt, warum ich diese Frage gestellt habe und warum ich gerne wissen möchte, warum Python sich von den anderen Sprachen unterscheidet:

Ich komme aus Sprachen, in denen Sie lernen, dass alles nur so öffentlich wie nötig sein sollte und nicht mehr. Der Grund dafür ist, dass dadurch Abhängigkeiten reduziert und der Code sicherer geändert werden kann. Die Python-Art, Dinge umgekehrt zu machen - angefangen von der Öffentlichkeit bis hin zum Verborgenen - ist für mich seltsam.

Paul Manta
quelle

Antworten:

182

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 = ageTeile 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 :)

brandizzi
quelle
1. Die Kapselung dient zum Schutz von Klasseninvarianten. Keine unnötigen Details vor der Außenwelt zu verbergen, weil es ärgerlich wäre. 2. "Der Punkt ist: Ihre API sollte gut sein und der Rest sind Details." Das ist wahr. Und öffentliche Attribute sind Teil Ihrer API. Manchmal sind auch öffentliche Setter angemessen (in Bezug auf Ihre Klasseninvarianten) und manchmal nicht. Eine API mit öffentlichen Setzern, die nicht öffentlich sein sollten (Risiko der Verletzung von Invarianten), ist eine schlechte API. Dies bedeutet, dass Sie ohnehin über die Sichtbarkeit jedes Setters nachdenken müssen und ein „Standard“ weniger bedeutet.
Jupiter
21

Erstens - Was ist Name Mangling?

Name Mangeln wird aufgerufen , wenn Sie in einer Klassendefinition und Verwendung sind __any_nameoder __any_name_, das ist zwei (oder mehr) führenden Unterstrichen und höchstens ein Unterstrich Hinter.

class Demo:
    __any_name = "__any_name"
    __any_other_name_ = "__any_other_name_"

Und nun:

>>> [n for n in dir(Demo) if 'any' in n]
['_Demo__any_name', '_Demo__any_other_name_']
>>> Demo._Demo__any_name
'__any_name'
>>> Demo._Demo__any_other_name_
'__any_other_name_'

Was tun Sie im Zweifelsfall?

Die angebliche Verwendung besteht darin, zu verhindern, dass Unterklassen ein Attribut verwenden, das die Klasse verwendet.

Ein möglicher Wert besteht darin, Namenskollisionen mit Unterklassen zu vermeiden, die das Verhalten überschreiben möchten, damit die übergeordnete Klassenfunktionalität wie erwartet funktioniert. Das Beispiel in der Python-Dokumentation ist jedoch nicht durch Liskov ersetzbar, und es fallen mir keine Beispiele ein, bei denen ich dies nützlich gefunden habe.

Die Nachteile sind, dass es die kognitive Belastung für das Lesen und Verstehen einer Codebasis erhöht, insbesondere beim Debuggen, bei dem der doppelte Unterstrich in der Quelle und ein verstümmelter Name im Debugger angezeigt werden.

Mein persönlicher Ansatz ist es, dies absichtlich zu vermeiden. Ich arbeite an einer sehr großen Codebasis. Die seltenen Verwendungszwecke ragen wie ein schmerzender Daumen heraus und scheinen nicht gerechtfertigt zu sein.

Sie müssen sich dessen bewusst sein, damit Sie es wissen, wenn Sie es sehen.

PEP 8

PEP 8 , dem Style Guide für die Python-Standardbibliothek, heißt es derzeit (gekürzt):

Es gibt einige Kontroversen über die Verwendung von __names .

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.

  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.

  2. Das Mangeln von Namen kann bestimmte Verwendungszwecke wie das Debuggen und __getattr__()weniger bequem machen. Der Name Mangling-Algorithmus ist jedoch gut dokumentiert und einfach manuell durchzuführen.

  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.

Wie funktioniert es?

Wenn Sie in einer Klassendefinition zwei Unterstriche voranstellen (ohne doppelte Unterstriche zu beenden), wird der Name entstellt, und dem Objekt wird ein Unterstrich gefolgt vom Klassennamen vorangestellt:

>>> class Foo(object):
...     __foobar = None
...     _foobaz = None
...     __fooquux__ = None
... 
>>> [name for name in dir(Foo) if 'foo' in name]
['_Foo__foobar', '__fooquux__', '_foobaz']

Beachten Sie, dass Namen nur dann entstellt werden, wenn die Klassendefinition analysiert wird:

>>> Foo.__test = None
>>> Foo.__test
>>> Foo._Foo__test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute '_Foo__test'

Außerdem haben Python-Neulinge manchmal Probleme zu verstehen, was vor sich geht, wenn sie nicht manuell auf einen Namen zugreifen können, den sie in einer Klassendefinition definiert sehen. Dies ist kein starker Grund dagegen, aber es ist etwas zu beachten, wenn Sie ein lernendes Publikum haben.

Ein Unterstrich?

Wenn die Konvention nur einen Unterstrich verwenden soll, würde ich auch gerne die Gründe kennen.

Wenn Benutzer beabsichtigen, ihre Hände von einem Attribut fernzuhalten, verwende ich normalerweise nur den einen Unterstrich. Dies liegt jedoch daran, dass Unterklassen in meinem mentalen Modell Zugriff auf den Namen haben (den sie immer haben, da sie den leicht erkennen können verstümmelter Name sowieso).

Wenn ich Code überprüfen würde, der das __Präfix verwendet, würde ich fragen, warum sie Namensverknüpfungen aufrufen und ob sie mit einem einzelnen Unterstrich nicht genauso gut zurechtkommen könnten, wobei zu berücksichtigen ist, dass Unterklassen dieselben Namen für die Klasse und wählen Klassenattribut Trotzdem kommt es zu einer Namenskollision.

Aaron Hall
quelle
15

Ich würde nicht sagen, dass Übung besseren Code erzeugt. Sichtbarkeitsmodifikatoren lenken Sie nur von der eigentlichen Aufgabe ab und erzwingen als Nebeneffekt, dass Ihre Benutzeroberfläche wie beabsichtigt verwendet wird. Im Allgemeinen verhindert das Erzwingen der Sichtbarkeit, dass Programmierer Dinge durcheinander bringen, wenn sie die Dokumentation nicht richtig gelesen haben.

Eine weitaus bessere Lösung ist der von Python empfohlene Weg: Ihre Klassen und Variablen sollten gut dokumentiert und ihr Verhalten klar sein. Die Quelle sollte verfügbar sein. Dies ist eine weitaus erweiterbarere und zuverlässigere Methode zum Schreiben von Code.

Meine Strategie in Python lautet:

  1. Schreiben Sie einfach das verdammte Ding, machen Sie keine Annahmen darüber, wie Ihre Daten geschützt werden sollen. Dies setzt voraus, dass Sie schreiben, um die idealen Schnittstellen für Ihre Probleme zu erstellen.
  2. Verwenden Sie einen führenden Unterstrich für Dinge, die wahrscheinlich nicht extern verwendet werden und nicht Teil der normalen "Client-Code" -Schnittstelle sind.
  3. Verwenden Sie einen doppelten Unterstrich nur für Dinge, die nur der Bequemlichkeit innerhalb der Klasse dienen oder bei versehentlichem Aussetzen erhebliche Schäden verursachen.

Vor allem sollte klar sein, was alles macht. Dokumentieren Sie es, wenn jemand anderes es verwenden wird. Dokumentieren Sie es, wenn Sie möchten, dass es in einem Jahr nützlich ist.

Als Randnotiz sollten Sie eigentlich mit geschützt in diesen anderen Sprachen arbeiten: Sie wissen nie, dass Ihre Klasse später geerbt werden könnte und wofür sie verwendet werden könnte. Am besten schützen Sie nur die Variablen, von denen Sie sicher sind, dass sie nicht von Fremdcode verwendet werden können oder sollten.

Matt Joiner
quelle
9

Sie sollten nicht mit privaten Daten beginnen und diese bei Bedarf veröffentlichen. Sie sollten zunächst die Schnittstelle Ihres Objekts herausfinden. Das heißt, Sie sollten zunächst herausfinden, was die Welt sieht (das öffentliche Zeug) und dann herausfinden, welches private Zeug dafür notwendig ist.

Andere Sprachen machen es schwierig, das, was einst öffentlich war, privat zu machen. Dh ich werde viel Code brechen, wenn ich meine Variable privat oder geschützt mache. Bei Eigenschaften in Python ist dies jedoch nicht der Fall. Vielmehr kann ich die gleiche Schnittstelle auch bei einer Neuordnung der internen Daten beibehalten.

Der Unterschied zwischen _ und __ besteht darin, dass Python tatsächlich versucht, letzteres durchzusetzen. Natürlich ist es nicht wirklich anstrengend, aber es macht es schwierig. Wenn _ anderen Programmierern lediglich die Absicht mitteilt, können sie diese auf eigene Gefahr ignorieren. Das Ignorieren dieser Regel ist jedoch manchmal hilfreich. Beispiele hierfür sind Debugging, temporäre Hacks und die Arbeit mit Code von Drittanbietern, der nicht so verwendet werden soll, wie Sie ihn verwenden.

Winston Ewert
quelle
6

Es gibt bereits viele gute Antworten darauf, aber ich werde eine andere anbieten. Dies ist teilweise auch eine Reaktion auf Leute, die immer wieder sagen, dass doppelter Unterstrich nicht privat ist (es ist wirklich so).

Wenn Sie sich Java / C # ansehen, haben beide private / protected / public. All dies sind Konstrukte zur Kompilierungszeit . Sie werden nur zum Zeitpunkt der Kompilierung durchgesetzt. Wenn Sie Reflection in Java / C # verwenden, können Sie problemlos auf die private Methode zugreifen.

Jedes Mal, wenn Sie eine Funktion in Python aufrufen, verwenden Sie von Natur aus Reflection. Diese Codeteile sind in Python identisch.

lst = []
lst.append(1)
getattr(lst, 'append')(1)

Die "Punkt" -Syntax ist nur syntaktischer Zucker für den letzteren Code. Meistens, weil die Verwendung von getattr mit nur einem Funktionsaufruf bereits hässlich ist. Von da an wird es nur noch schlimmer.

Also damit kann es nicht Java / C # -Version von private geben, da Python den Code nicht kompiliert. Java und C # können zur Laufzeit nicht überprüfen, ob eine Funktion privat oder öffentlich ist, da diese Informationen nicht mehr vorhanden sind (und sie nicht wissen, woher die Funktion aufgerufen wird).

Mit diesen Informationen ist die Namensverflechtung des doppelten Unterstrichs am sinnvollsten, um "Privatität" zu erreichen. Wenn nun eine Funktion von der 'self'-Instanz aufgerufen wird und feststellt, dass sie mit' __ 'beginnt, führt sie genau dort den Namen mangling aus. Es ist nur mehr syntaktischer Zucker. Dieser syntaktische Zucker ermöglicht das Äquivalent von "privat" in einer Sprache, die nur die Reflexion für den Zugriff auf Datenelemente verwendet.

Haftungsausschluss: Ich habe noch nie jemanden aus der Python-Entwicklung so etwas sagen hören. Der wahre Grund für das Fehlen von "privat" ist kulturell, aber Sie werden auch feststellen, dass die meisten Skriptsprachen / interpretierten Sprachen keine privaten haben. Ein streng durchsetzbarer Privatmann ist nur zur Kompilierungszeit praktikabel.

Jonathan Sternberg
quelle
4

Erstens: Warum möchten Sie Ihre Daten verbergen? Warum ist das so wichtig?

Meistens willst du es nicht wirklich tun, aber du tust es, weil andere es tun.

Wenn Sie wirklich wirklich wirklich nicht wollen, dass Leute etwas benutzen, fügen Sie eins hinzu Unterstrich davor hinzu. Das war's ... Pythonisten wissen, dass Dinge mit einem Unterstrich nicht jedes Mal garantiert funktionieren und sich ändern können, ohne dass Sie es wissen.

So leben wir und damit sind wir einverstanden.

Wenn Sie zwei Unterstriche verwenden, wird Ihre Klasse für die Unterklasse so schlecht, dass selbst Sie nicht so arbeiten möchten.

JBernardo
quelle
2
Sie haben den Grund weggelassen, warum doppelter Unterstrich für Unterklassen schlecht ist ... dies würde Ihre Antwort verbessern.
Matt Joiner
2
Angesichts der Tatsache, dass die doppelten Unterstriche eigentlich nur dazu dienen, Namenskollisionen mit Unterklassen zu verhindern (um Unterklassen "Hände weg" zu sagen), sehe ich nicht, wie das Mangeln von Namen ein Problem verursacht.
Aaron Hall
4

Die gewählte Antwort erklärt gut, wie Eigenschaften die Notwendigkeit privater Attribute beseitigen , aber ich möchte auch hinzufügen, dass Funktionen auf Modulebene die Notwendigkeit privater Methoden beseitigen .

Wenn Sie eine Methode auf Modulebene in eine Funktion umwandeln, entfernen Sie die Möglichkeit für Unterklassen, diese zu überschreiben. Das Verschieben einiger Funktionen auf die Modulebene ist pythonischer als der Versuch, Methoden mit Namensverknüpfung auszublenden.

Tanner_Wauchope
quelle
3

Das folgende Code-Snippet erklärt alle verschiedenen Fälle:

  • zwei führende Unterstriche (__a)
  • einzelner führender Unterstrich (_a)
  • kein Unterstrich (a)

    class Test:
    
    def __init__(self):
        self.__a = 'test1'
        self._a = 'test2'
        self.a = 'test3'
    
    def change_value(self,value):
        self.__a = value
        return self.__a

Drucken aller gültigen Attribute des Testobjekts

testObj1 = Test()
valid_attributes = dir(testObj1)
print valid_attributes

['_Test__a', '__doc__', '__init__', '__module__', '_a', 'a', 
'change_value']

Hier können Sie sehen, dass der Name von __a in _Test__a geändert wurde, um zu verhindern, dass diese Variable von einer der Unterklassen überschrieben wird. Dieses Konzept ist in Python als "Name Mangling" bekannt. Sie können folgendermaßen darauf zugreifen:

testObj2 = Test()
print testObj2._Test__a

test1

In ähnlicher Weise dient die Variable im Fall von _a nur dazu, den Entwickler darüber zu informieren, dass sie als interne Variable dieser Klasse verwendet werden soll. Der Python-Interpreter führt auch dann keine Aktionen aus, wenn Sie darauf zugreifen. Dies ist jedoch keine gute Vorgehensweise.

testObj3 = Test()
print testObj3._a

test2

Auf eine Variable kann von überall aus zugegriffen werden, wie bei einer öffentlichen Klassenvariablen.

testObj4 = Test()
print testObj4.a

test3

Hoffe die Antwort hat dir geholfen :)

Nitish Chauhan
quelle
2

Auf den ersten Blick sollte es das gleiche sein wie für andere Sprachen (unter "andere" meine ich Java oder C ++), aber es ist nicht so.

In Java haben Sie alle Variablen privat gemacht, auf die außerhalb nicht zugegriffen werden sollte. Gleichzeitig kann man dies in Python nicht erreichen, da es keine "Privatsphäre" gibt (wie eines der Python-Prinzipien sagt - "Wir sind alle Erwachsene"). Ein doppelter Unterstrich bedeutet also nur "Leute, benutzt dieses Feld nicht direkt". Dieselbe Bedeutung hat einen einzigen Unterstrich, der gleichzeitig keine Kopfschmerzen verursacht, wenn Sie von einer betrachteten Klasse erben müssen (nur ein Beispiel für ein mögliches Problem, das durch einen doppelten Unterstrich verursacht wird).

Daher würde ich Ihnen empfehlen, standardmäßig einen einzelnen Unterstrich für "private" Mitglieder zu verwenden.

Roman Bodnarchuk
quelle
Verwenden Sie einen doppelten Unterstrich für "privat" und einen einfachen Unterstrich für "geschützt". Normalerweise verwenden die Leute nur einen einfachen Unterstrich für alles (ein doppelter Unterstrich hilft dabei, die Privatsphäre zu erzwingen, was normalerweise gegen den Python-Stil verstößt).
Jonathan Sternberg
1
Aber macht das nicht zwei Unterstriche ähnlich wie privat und einen Unterstrich ähnlich wie geschützt? Warum nicht einfach von "privat" ausgehen?
Paul Manta
@ Paul Nein, das tut es nicht. Es gibt kein privates in Python und Sie sollten nicht versuchen, es zu erreichen.
Roman Bodnarchuk
@Roman Konzeptionell gesehen ... Beachten Sie die Anführungszeichen um 'privat'.
Paul Manta
1

"Wenn Sie Zweifel haben, ob eine Variable privat oder geschützt sein soll, ist es besser, privat zu gehen." - Ja, das gilt auch für Python.

Einige Antworten hier sagen über "Konventionen" aus, geben aber keine Links zu diesen Konventionen an. Der maßgebliche Leitfaden für Python, PEP 8, besagt ausdrücklich:

Im Zweifelsfall wählen Sie nicht öffentlich; Es ist einfacher, es später öffentlich zu machen, als ein öffentliches Attribut nicht öffentlich zu machen.

Die Unterscheidung zwischen öffentlich und privat sowie die Namensverfälschung in Python wurden in anderen Antworten berücksichtigt. Aus dem gleichen Link,

Wir verwenden hier nicht den Begriff "privat", da in Python kein Attribut wirklich privat ist (ohne generell unnötigen Arbeitsaufwand).

Jaroslaw Nikitenko
quelle