Frage

Angenommen, ich eine Klasse mit einigen Attributen haben. Wie ist es am besten (im Pythonic-OOP) Sinn, diese Attribute zugreifen? Genau wie obj.attr? Oder schreiben Sie vielleicht Accessoren bekommen? Was sind die akzeptiert Namensgebung Stile für solche Dinge?

Edit: Können Sie sich an den Best Practices von erarbeiten Attribute mit einem einfachen oder doppelten Unterstrich zu benennen? Ich sehe in den meisten Module, die ein Unterstrich verwendet wird.


Wenn diese Frage bereits gestellt (und ich habe das Gefühl, es hat, wenn die Suche Ergebnisse nicht bringen), bitte darauf zeigen -. Und ich werde diese ein schließen

War es hilfreich?

Lösung

Die allgemein akzeptierte Art und Weise, Dinge zu tun ist, mit nur einfachen Attributen, wie so

>>> class MyClass:
...     myAttribute = 0
... 
>>> c = MyClass()
>>> c.myAttribute 
0
>>> c.myAttribute = 1
>>> c.myAttribute
1

Wenn Sie selbst finden brauchen Lage sein, Getter und Setter zu schreiben, dann, was Sie suchen wollen, ist „Python-Klasse Eigenschaften“ und Ryan Tomayko Artikel über Getter / Setters / Fuxors ein großartiger Ort ist (wenn auch ein wenig lang) zu starten

Andere Tipps

Im Hinblick auf die Einzel- und Doppelführenden Unterstrichen: beide zeigen das gleiche Konzept der ‚Privatheit‘. Das heißt, die Menschen das Attribut wissen (wäre es ein Verfahren oder ein ‚normales‘ Datenattribut oder irgendetwas anderes) ist nicht Teil der öffentlichen API des Objekts. Die Leute werden wissen, dass es direkt zu berühren ist Katastrophe einzuladen.

Hinzu kommt, dass die Doppel führende Attribute unterstreichen (aber nicht der einzige Unterstrich Attribute) ist name-zerfleischt , um den Zugriff auf sie zufällig von Subklassen oder anderswo außerhalb der aktuellen Klasse weniger wahrscheinlich. Sie können sie immer noch zugreifen, aber nicht so trivial. Zum Beispiel:

>>> class ClassA:
...     def __init__(self):
...         self._single = "Single"
...         self.__double = "Double"
...     def getSingle(self):
...         return self._single
...     def getDouble(self):
...         return self.__double
... 
>>> class ClassB(ClassA):
...     def getSingle_B(self):
...         return self._single
...     def getDouble_B(self):
...         return self.__double
... 
>>> a = ClassA()
>>> b = ClassB()

Sie können nun trivialen Zugang a._single und b._single und erhalten das _single Attribut von ClassA erstellt:

>>> a._single, b._single
('Single', 'Single')
>>> a.getSingle(), b.getSingle(), b.getSingle_B()
('Single', 'Single', 'Single')

Doch der Versuch, das __double Attribut auf der a oder b Instanz zugreifen direkt nicht:

>>> a.__double
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: ClassA instance has no attribute '__double'
>>> b.__double
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: ClassB instance has no attribute '__double'

Und obwohl in ClassA definierten Methoden können sie erhalten direkt (wenn auf jedem Fall genannt):

>>> a.getDouble(), b.getDouble()
('Double', 'Double')

Methoden definiert auf ClassB kann nicht:

>>> b.getDouble_B()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in getDouble_B
AttributeError: ClassB instance has no attribute '_ClassB__double'

Und gerade in diesem Fehler erhalten Sie einen Hinweis darüber, was passiert. Der __double Attributname, wenn in einer Klasse zugegriffen wird name-verstümmelt ist, um die Namen der Klasse gehören, die auf diese zugegriffen wird in . Wenn ClassA versucht self.__double zugreifen, es stellt sich tatsächlich - bei compiletime - in einem Anfall von self._ClassA__double, und ebenfalls für ClassB. (Wenn eine Methode in ClassB zuzuordnen waren, __double der Kürze halber nicht im Code enthalten, wäre es nicht ClassA der __double dafür berühren, aber ein neues Attribut erstellen.) Es gibt keinen anderen Schutz dieses Attribut, so können Sie es immer noch direkt zugreifen wenn Sie die richtigen Namen kennen:

>>> a._ClassA__double, b._ClassA__double
('Double', 'Double')

Warum ist das ein Problem?

Nun, es ist ein Problem, wann immer Sie wollen das Verhalten von Code erben, und ändern Sie mit diesem Attribut handelt. Sie müssen entweder alles neu zu implementieren, die dieser Doppelstrich direkt Attribut berührt, oder Sie haben an den Klassennamen zu erraten und den Namen manuell mangle. Das Problem wird noch schlimmer, wenn diese Doppelstrich Attribut ist eigentlich eine Methode: Überschreiben der Methode oder die Methode in einer Unterklasse Aufruf bedeutet, den Namen-Mangeln tun manuell, oder den gesamten Code Neuimplementierung, die die Methode ruft verwenden Sie die Doppelstrich Namen nicht. Ganz zu schweigen von dem Attribut dynamisch, mit getattr() Zugriff. Sie müssen manuell es mangle auch

Auf der anderen Seite, da das Attribut nur trivialen neu geschrieben, bietet es nur oberflächlich ‚Schutz‘. Jedes Stück Code kann immer noch auf dem Attribute erhalten, indem manuell Mangeln, obwohl das machen ihre Code abhängig von dem Namen Ihre Klasse und Anstrengungen auf Ihrer Seite zu Refaktorieren Code oder benennen Sie Ihre Klasse (während immer noch die gleichen Benutzer sichtbaren Namen halten, eine gängige Praxis in Python) unnötig ihren Code brechen. Sie können ‚Trick‘ Python auch in den Namen-Mangeln tun für sie durch ihre Klasse Namensgebung das gleiche wie Sie: bemerken, wie es keine Modulnamen in der verstümmelten Attributnamen enthalten ist. Und schließlich ist der Doppelstrich Attribut noch sichtbar in allen Listen-Attribute und alle Formen der Selbstbeobachtung, die Pflege nicht nehmen Attribute zu überspringen, beginnend mit a ( Single ) Strich.

So , wenn Sie verwenden Doppelstrich Namen, sie verwenden sehr sparsam, da sie sehr unbequem herausstellen können, und sie nie für Methoden oder irgendetwas anderes eine Unterklasse jemals möchten neu zu implementieren, überschreiben oder den Zugang direkt . Und erkennen, dass doppelt führenden Unterstrich Name-Mangeln Angebote kein wirklicher Schutz . Am Ende eines einzigen Unterstrich unter Verwendung gewinnt man nur so viel und gibt Ihnen weniger (Potential, Zukunft) Schmerzen. Verwenden Sie einen einzigen Unterstrich.

  

Edit: Können Sie sich an den Best Practices erarbeiten von Attributen mit einem einfachen oder doppelten Unterstrich zu benennen? Ich sehe in den meisten Module, die ein Unterstrich verwendet wird.

Single Strich nichts Besonderes zu Python bedeutet, es ist nur beste Praxis, zu sagen, „hey Sie wollen wahrscheinlich nicht diese zugreifen, wenn Sie wissen, was Sie tun“. jedoch Doppelstrich macht Python nur aus der Klasse die Namen intern zugänglich zu machen mangle, wo sie definiert ist.

Doppel Vorder- und Hinterstrich bezeichnet eine spezielle Funktion, wie __add__, die aufgerufen wird, wenn der Bediener + verwendet wird.

Lesen Sie mehr in PEP 8 , vor allem die "Namenskonventionen" Abschnitt.

Ich denke, die meisten sie nur direkt zugreifen, keine Notwendigkeit für get / set-Methoden.

>>> class myclass:
...     x = 'hello'
...
>>>
>>> class_inst = myclass()
>>> class_inst.x
'hello'
>>> class_inst.x = 'world'
>>> class_inst.x
'world'

BTW, können Sie die dir () Funktion, um zu sehen verwenden, welche Attribute / Methoden zu Ihrer Instanz gebunden sind:

>>> dir(class_inst)
['__doc__', '__module__', 'x']

Zwei führende Unterstriche, „__“ wird verwendet, um ein Attribut zu machen oder privat funktionieren. Für andere Konventionen siehe PEP 08: http://www.python.org/dev/peps/pep-0008/

Python muss nicht Accessoren von Anfang an definieren, da Attributen in dem Eigentum Umwandlung ist schnell und schmerzlos. Im Folgenden finden Sie eine anschauliche Demonstration:

Erholung von Sucht

Es gibt keinen wirklichen Punkt zu tun Getter / Setter in Python, können Sie nicht Sachen sowieso schützen und wenn Sie einige zusätzliche Code ausführen müssen, wenn immer / die Eigenschaft Blick auf die Eigenschaft festlegen () builtin (python -c ' Hilfe (Eigentum) ')

Einige Leute benutzen Getter und Setter. Je nachdem, welche Codierung Stil verwenden Sie Sie sie getSpam und seteggs benennen. Sie können aber auch nur lesbar oder weisen nur machen Sie Attribute. Das ist ein bisschen zu tun umständlich. Eine Möglichkeit ist, überschreibt die

> __getattr__

und

> __setattr__

Methoden.

Edit:

Während meine Antwort ist immer noch wahr ist, es ist nicht richtig, als ich kam zu realisieren. Es gibt bessere Möglichkeiten Accessoren in Python und sind nicht sehr umständlich.

zu machen
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top