Frage

Ich bin aus der Java-Welt kommen und Bruce Eckel Python 3 Patterns, Rezepte und Idioms zu lesen.

Während über die Klassen zu lesen, geht es weiter zu sagen, dass in Python gibt es keine Notwendigkeit Instanzvariablen zu erklären ist. Sie verwenden sie nur im Konstruktor und boom, sind sie da.

So zum Beispiel:

class Simple:
    def __init__(self, s):
        print("inside the simple constructor")
        self.s = s

    def show(self):
        print(self.s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

Wenn das wahr ist, dann jedes Objekt der Klasse Simple kann nur den Wert der Variablen s ändern außerhalb der Klasse.

Zum Beispiel:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

In Java haben wir über öffentlich / privat / protected Variablen gelehrt. Diese Schlüsselwörter sind sinnvoll, weil manchmal Sie Variablen in einer Klasse wollen, auf die niemand außerhalb der Klasse Zugriff hat.

Warum ist das nicht erforderlich ist in Python?

War es hilfreich?

Lösung

Es ist kulturell. In Python, schreiben Sie nicht auf andere Klassen-Instanz oder Klassenvariablen. In Java verhindert, dass Sie nichts von das gleiche zu tun, wenn Sie wirklich zu wollen - schließlich können Sie immer die Quelle der Klasse bearbeiten sich um den gleichen Effekt zu erzielen. Python Tropfen, die Vortäuschung von Sicherheit und ermutigt Programmierer verantwortlich zu sein. In der Praxis funktioniert dies sehr gut.

Wenn Sie private Variablen aus irgendeinem Grund emulieren wollen, können Sie immer die __ Präfix von PEP 8 . Python mangles die Namen von Variablen wie __foo, so dass sie Code außerhalb der Klasse nicht leicht sichtbar sind, das sie enthält (obwohl Sie können um ihn herum, wenn man genug bestimmt sind, so wie du em < > können erhalten Schutz rund um Java, wenn Sie daran arbeiten).

Mit der gleichen Konvention, die _ Präfix Mittel bleiben weg, auch wenn Sie nicht technisch zu tun, verhindert sind so . Sie müssen nicht mit einer anderen Klasse der Variablen spielen, um die wie __foo oder _bar aussehen.

Andere Tipps

Privat Variablen in Python ist mehr oder weniger ein Hack. Der Interpreter absichtlich die Variable umbenennt

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

Nun, wenn Sie versuchen, __var außerhalb der Klassendefinition zuzugreifen, wird fehlschlagen:

 >>>x = A()
 >>>x.__var # this will return error: "A has no attribute __var"

 >>>x.printVar() # this gives back 123

Sie können aber mit diesem leicht wegkommen:

 >>>x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

 >>>x._A__var = 456 # you now know the masked name of private variables
 >>>x.printVar() # this gives back 456

Sie wissen wahrscheinlich, dass Methoden in OOP aufgerufen werden wie folgt aus: x.printVar() => A.printVar(x), wenn A.printVar() einige Feld in x zugreifen können, kann dieses Feld auch zugegriffen werden außerhalb A.printVar() ... immerhin Funktionen erstellt werden für Wiederverwertbarkeit, gibt es keine besondere Kraft in den Erklärungen gegeben.

Das Spiel ist anders, wenn es ein Compiler ist beteiligt ( Der Datenschutz ist ein Compiler Level-Konzept ). Es weiß über Klassendefinition mit Zugriffskontrolle Modifikatoren so kann es Fehler aus, wenn die Regeln nicht während der Kompilierung befolgt werden

Wie richtig von vielen der Kommentare oben erwähnt, lassen Sie uns nicht das Hauptziel der Zugriffsmodifizierer vergessen: Benutzer von Code zu helfen, zu verstehen, was soll sich ändern und was soll nicht zu. Wenn Sie einen privaten Bereich sehen müssen Sie nicht herumspielen mit ihm. So ist es meist syntaktischer Zucker, die leicht in Python erreicht wird durch die _ und __.

"In Java haben wir über öffentliche / private / protected Variablen gelehrt worden"

"Warum ist das nicht in Python erforderlich?"

Aus dem gleichen Grunde ist es nicht erforderlich in Java.

Sie sind kostenlos zu benutzen -. Oder nicht verwenden private und protected

Als Python und Java-Programmierer habe ich festgestellt, dass private und protected sind sehr, sehr wichtige Design-Konzepte. Aber als eine praktische Angelegenheit, in Zehntausende von Zeilen Java und Python, ich habe eigentlich nie verwendet private oder protected.

Warum nicht?

Hier ist meine Frage „geschützt von wem?“

Andere Programmierer in meinem Team? Sie haben die Quelle. Was bedeutet geschützt meinen, wenn sie es ändern?

Andere Programmierer auf anderen Teams? Sie arbeiten für die gleiche Firma. Sie können - mit einem Telefonanruf -. Bekommen die Quelle

Kunden? Es ist Arbeit-for-hire Programmierung (im Allgemeinen). Die Clients (im Allgemeinen) besitzen den Code.

Also, wer - genau - am Schutz ich es von

?

Es ist eine Variation von privaten Variablen in der Unterstrich-Konvention.

In [5]: class Test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:     

In [6]: x = Test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'Test' object has no attribute '__private_method'

Es gibt einige feine Unterschiede, aber im Interesse der Programmiermuster ideologische Reinheit, seine gut genug.

Es gibt Beispiele dort aus @private Dekorateure, die mehr das Konzept eng implementieren, aber YMMV. Wohl konnte man auch eine Klasse defintion schreiben, die Meta verwendet

Python hat eine begrenzte Unterstützung für private Identifikatoren, durch eine Funktion, die den Klassennamen auf alle Kennungen, beginnend mit zwei Unterstrichen automatisch prepends. Dies ist für den Programmierer transparent, zum größten Teil, aber der Nettoeffekt ist, dass alle auf diese Weise benannten Variablen können als private Variablen verwendet werden.

Siehe hier mehr dazu.

Im Allgemeinen Python-Implementierung von Objektorientierung ist ein bisschen primitiv im Vergleich zu anderen Sprachen. Aber ich genieße diese, eigentlich. Es ist eine sehr konzeptionell einfache Implementierung und paßt gut mit dem dynamischen Stil der Sprache.

Wie bereits erwähnt, können Sie angeben, dass eine Variable oder Methode privat ist, indem sie es mit einem Unterstrich voranstellen. Wenn Sie nicht das Gefühl, wie dies genug ist, können Sie immer die property Dekorateur verwenden. Hier ein Beispiel:

class Foo:

    def __init__(self, bar):
        self._bar = bar

    @property
    def bar(self):
        """Getter for '_bar'."""
        return self._bar

Auf diese Weise, jemand oder etwas, das bar verweist tatsächlich verweist auf den Rückgabewert der bar Funktion eher als die Variable selbst, und deshalb kann es erreicht werden, aber nicht verändert. Allerdings, wenn jemand wirklich will, sie könnten einfach _bar verwenden und einen neuen Wert zuweisen. Es gibt keine todsichere Methode, um jemanden zu verhindern, dass Variablen und Methoden zugreifen, die Sie ausblenden möchten, wie immer wieder gesagt worden ist. Allerdings property Verwendung ist das deutlichste Meldung, dass eine Variable nicht bearbeitet werden soll, senden kann. property kann auch für komplexere Getter / Setter / deleter Zugriffspfade verwendet werden, wie hier erläutert:

Das einzige Mal, immer ich private Variablen verwenden, wenn ich andere Dinge tun müssen, wenn zu schreiben oder aus der Variablen zu lesen und als solche ich brauche die Verwendung eines Setter und / oder Getter zu erzwingen.

Auch hier geht dies zu Kultur, wie bereits erwähnt. Ich habe an Projekten gearbeitet, wo das Lesen und Schreiben von anderen Klassen Variablen frei für alles war. Bei einer Implementierung veraltet wurde dauerte es viel länger alle Codepfade zu identifizieren, die diese Funktion verwendet. Bei Verwendung von Getter und Setter gezwungen wurde, kann eine Debug-Anweisung leicht geschrieben werden, um zu erkennen, dass die veraltete Methode aufgerufen worden ist und der Codepfad, der es nennt.

Wenn Sie an einem Projekt, wo jemand eine Erweiterung schreiben kann, Benutzer über veraltete Methoden darüber informiert, dass daher in einigen Versionen verschwinden sind, ist von entscheidenden Bedeutung Modul Bruch bei einem Minimum bei Upgrades zu halten.

So ist meine Antwort; wenn Sie und Ihre Kollegen einen einfachen Code halten und stellen Sie dann den Schutz Variablen Klasse ist nicht immer notwendig. Wenn Sie ein erweiterbares System schreiben, dann wird es zwingend notwendig, wenn Änderungen an den Kern hergestellt werden, die von allen Erweiterungen gefangen werden muss, mit dem Code.

private und geschützte Konzepte sind sehr wichtig. Aber Python - nur ein Werkzeug für das Prototyping und schnelle Entwicklung mit eingeschränkten Ressourcen für die Entwicklung, deshalb sind einige Schutzstufen nicht so streng in Python gefolgt. Sie können „__“ in der Klasse Elemente verwenden, es funktioniert, sieht aber nicht gut genug - jeder Zugriff auf derartiges Feld diese Zeichen enthält.

Sie können aber auch bemerkt, dass Python OOP-Konzept ist nicht perfekt, smaltalk oder Rubin viel näher an reinem OOP-Konzept. Auch C # oder Java ist näher.

Python ist sehr gutes Werkzeug. Aber es ist vereinfachte OOP-Sprache. Syntaktisch und konzeptionell vereinfacht. Das Hauptziel der Python Existenz ist, um Entwicklern die Möglichkeit zu bringen, leicht lesbaren Code mit einer hohen Abstraktionsebene in einer sehr schnellen Weise zu schreiben.

Sorry Leute für den Thread "wiederzubeleben", aber ich hoffe, dass dies jemand helfen:

In Python3, wenn Sie nur wollen „einkapseln“ die Klassenattribute, wie in Java, können Sie einfach das Gleiche tun, wie folgt:

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

Sie dazu So instantiieren:

ss = Simple("lol")
ss.show()

Beachten Sie, dass:. print(ss.__s) wird einen Fehler werfen

In der Praxis wird Python3 verschleiert die globalen Attributnamen. Turning dies wie ein "privates" Attribut, wie in Java. Das Name des Attributs ist nach wie vor global, sondern in einer unzugänglichen Art und Weise, wie ein privates Attribut in anderen Sprachen.

Aber seien Sie keine Angst davor. Es spielt keine Rolle. Es macht den zu Job. ;)

Python hat keine privaten Variablen wie C ++ oder Java tut. Sie könnten jedes Mitglied Variable jederzeit zugreifen, wenn auch wollte. Allerdings müssen Sie nicht private Variablen in Python, weil in Python es nicht schlecht ist Ihre Klassen Membervariablen zu belichten. Wenn Sie das Bedürfnis haben, eine Membervariable zu verkapseln, können Sie dies tun, indem Sie „@property“ wiederzufinden, ohne zu brechen bestehende Client-Code.

In Python des einzelne Unterstrich „_“ wird verwendet, um anzuzeigen, dass ein Verfahren oder eine Variable nicht als Teil des öffentlichen api einer Klasse betrachtet wird und dass dieser Teil der api zwischen verschiedenen Versionen ändern könnte. Sie können diese Methoden / Variablen verwenden, aber Ihr Code könnte brechen, wenn Sie eine neuere Version dieser Klasse verwenden.

Der Doppelstrich „__“ bedeutet nicht, eine „private Variable“. Sie verwenden es, Variablen zu definieren, die „Klasse local“ sind und welche nicht leicht durch Unterklassen außer Kraft gesetzt werden. Es mangles den Variablen-Namen.

Zum Beispiel:

class A(object):
    def __init__(self):
        self.__foobar = None # will be automatically mangled to self._A__foobar

class B(A):
    def __init__(self):
        self.__foobar = 1 # will be automatically mangled to self._B__foobar

Selbst .__ Name foobar wird automatisch in der Klasse B zu self._A__foobar in der Klasse A. verstümmelt es self._B__foobar verstümmelt ist. So kann jeder Unterklasse eine eigene Variable __foobar definieren, ohne zwingende seine Eltern Variable (n). Aber nichts hindert Sie daran, den Zugriff auf Variablen mit doppelten Unterstrichen beginnen. Allerdings Name-Mangeln verhindert, dass Sie beim Aufruf dieser Variablen / Methoden übrigens.

Ich empfehle stark Raymond Hettingers sprechen „Pythons Klasse Entwicklungs-Toolkit“ von PyCon 2013 (sollte auf Youtube verfügbar sein) zu sehen, die ein gutes Beispiel gibt, warum und wie Sie @property und „__“ verwenden sollten -. Instanzvariablen

scroll top