1859 Stimmen

Welche Bedeutung haben einfache und doppelte Unterstriche vor einem Objektnamen?

Kann jemand bitte erklären, die genaue Bedeutung der mit einfachen und doppelten führenden Unterstrichen vor einem Objektnamen in Python, und der Unterschied zwischen beiden?

Bleibt diese Bedeutung auch gleich, unabhängig davon, ob es sich bei dem betreffenden Objekt um eine Variable, eine Funktion, eine Methode usw. handelt?

6 Stimmen

Eine tolle kurze Antwort aus einem anderen Thread: stackoverflow.com/a/8689983/911945

1 Stimmen

Siehe auch dies ausgezeichnet Hier finden Sie eine Antwort auf die Frage nach einfachen und doppelten Unterstrichen und eine Demonstration der "Namensverwechslung"! Antwort auf "Private Mitglieder in Python"

96voto

Feuda Punkte 2065

Selon Bedeutung der Unterstriche in Python

  • Einfacher führender Unterstrich( _var ) : Namenskonvention, die angibt, dass ein Name für den internen Gebrauch bestimmt ist. Wird im Allgemeinen nicht vom Python-Interpreter durchgesetzt (außer bei Wildcard-Importen) und ist nur als Hinweis für den Programmierer gedacht.
  • Einfacher nachgestellter Unterstrich( var_ ) : Wird per Konvention verwendet, um Namenskonflikte mit Python-Schlüsselwörtern zu vermeiden.
  • Doppelt führender Unterstrich( __var ) : Löst Namensverwechslung aus, wenn es in einem Klassenkontext verwendet wird. Wird vom Python-Interpreter erzwungen.
  • Doppelte führende und nachgestellte Unterstriche( __var__ ) : Bezeichnet spezielle Methoden, die von der Sprache Python definiert werden. Vermeiden Sie dieses Namensschema für Ihre eigenen Attribute.
  • Einzelne Unterstreichung( _ ) : Wird manchmal als Bezeichnung für temporäre oder unbedeutende Variablen verwendet ("don't care"). Auch: Das Ergebnis des letzten Ausdrucks in einer Python REPL .

21voto

laike9m Punkte 16436

Da sich so viele Leute auf Raymonds sprechen Ich mache es mir ein wenig leichter, indem ich aufschreibe, was er gesagt hat:

Bei den doppelten Unterstrichen ging es nicht um die Privatsphäre. Die Absicht war, sie 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 um Freiheit. Ihre Unterklassen können eine beliebige Methode außer Kraft setzen, ohne die anderen zu beeinträchtigen. .

Angenommen, Sie behalten keine lokale Referenz von perimeter en Circle . Nun, eine abgeleitete Klasse Tire übersteuert die Implementierung von perimeter , ohne Berührung area . Wenn Sie anrufen Tire(5).area() sollte es theoretisch immer noch mit Circle.perimeter für die Berechnung, aber in Wirklichkeit verwendet es Tire.perimeter was nicht das beabsichtigte Verhalten ist. Deshalb brauchen wir eine lokale Referenz in Circle.

Aber warum __perimeter 代わりに _perimeter ? Weil _perimeter gibt abgeleiteten Klassen immer noch die Möglichkeit, zu überschreiben:

class Tire(Circle):

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

    _perimeter = perimeter

Doppelte Unterstriche führen zu einer Namensvermischung, so dass die Wahrscheinlichkeit, dass die lokale Referenz in der übergeordneten Klasse in der abgeleiteten Klasse überschrieben wird, sehr gering ist. macht es Ihren Unterklassen möglich, eine beliebige Methode zu überschreiben, ohne die anderen zu zerstören ".

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

1 Stimmen

Danke, die Folie wurde nicht richtig angezeigt, so dass ich am Ende nicht untersanting, warum mein Code fehlschlagen würde.

0 Stimmen

Hmm, ich habe die gleiche Antwort bekommen, egal ob der Perimeter einen führenden Dunder hatte oder nicht.

20voto

Tim D Punkte 1605

Manchmal haben Sie etwas, das wie ein Tupel aussieht, mit einem führenden Unterstrich wie in

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

In diesem Fall ist _() ein Alias für eine Lokalisierungsfunktion, die den Text je nach Gebietsschema in die richtige Sprache usw. übersetzt. Sphinx zum Beispiel tut dies, und Sie finden unter den Importen

from sphinx.locale import l_, _

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

18voto

Mathieu Rollet Punkte 1483
  • _var Variablen mit einem führenden einfachen Unterstrich in Python sind klassische Variablen, die dazu gedacht sind, andere, die Ihren Code benutzen, darüber zu informieren, dass diese Variable für den internen Gebrauch reserviert sein sollte. Sie unterscheiden sich in einem Punkt von den klassischen Variablen: Sie werden nicht importiert, wenn ein Wildcard-Import eines Objekts/Moduls durchgeführt wird, in dem sie definiert sind (Ausnahmen bei der Definition der __all__ variabel ). Beispiel:

    # foo.py
    
    var = "var"
    _var = "_var"
    
    # bar.py
    
    from foo import *
    
    print(dir())  # list of defined objects, contains 'var' but not '_var'
    print(var)    # var
    print(_var)   # NameError: name '_var' is not defined
  • _ : Der einfache Unterstrich ist ein Spezialfall der führenden einfachen Unterstrich-Variablen. Er wird vereinbarungsgemäß als Papierkorbvariable verwendet, um einen Wert zu speichern, auf den später nicht mehr zugegriffen werden soll. Er wird auch nicht durch Wildcard-Importe importiert. Beispiel: this for Schleife druckt 10 Mal "Ich darf im Unterricht nicht reden" und muss nie auf die _ variabel.

    for _ in range(10):
        print("I must not talk in class")
  • var_ : Variablen mit einfachem Unterstrich am Ende. Sie sind klassische Variablen, die aus Konvention verwendet werden, um Konflikte mit Python-Schlüsselwörtern zu vermeiden. Beispiel:

    class_ = "MyClassName"
  • __var Variablen mit doppelt führenden Unterstrichen (mindestens zwei führende Unterstriche, höchstens ein nachgestellter Unterstrich). Wenn sie als Klassenattribute (Variablen und Methoden) verwendet werden, unterliegen diese Variablen der Namensverfälschung: Außerhalb der Klasse benennt Python das Attribut um in _<Class_name>__<attribute_name> . Beispiel:

    class MyClass:
        __an_attribute = "attribute_value"
    
    my_class = MyClass()
    print(my_class._MyClass__an_attribute)  # "attribute_value"
    print(my_class.__an_attribute)  # AttributeError: 'MyClass' object has no attribute '__an_attribute'

    Wenn sie als Variablen außerhalb einer Klasse verwendet werden, verhalten sie sich wie Variablen mit einem führenden Unterstrich.

  • __var__ : Doppelt führende und nachgestellte Unterstrichvariablen (mindestens zwei führende und nachgestellte Unterstriche). Auch genannt dunders . Diese Namenskonvention wird von Python verwendet, um Variablen intern zu definieren. Vermeiden Sie die Verwendung dieser Konvention, um Namenskonflikte zu vermeiden, die bei Aktualisierungen von Python auftreten könnten. Dunder-Variablen verhalten sich wie einfache führende Unterstrich-Variablen: Sie unterliegen nicht der Namensvermischung, wenn sie innerhalb von Klassen verwendet werden, werden aber nicht in Wildcard-Importen importiert.

8voto

Dev Maha Punkte 1133

Wenn man eine Variable wirklich schreibgeschützt machen will, wäre es IMHO am besten, property() zu verwenden, dem nur getter übergeben wird. Mit property() können wir die vollständige Kontrolle über die Daten haben.

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, die nach "wie man private Variablen setzt" fragt, die als Duplikat mit dieser Frage markiert ist, dachte ich, dass ich diese zusätzlichen Informationen hier hinzufügen sollte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X