Verwenden einer Klasseninstanz als Klassenattribut, Deskriptoren und Eigenschaften

8

Ich habe kürzlich festgestellt, dass ich versuche, den neueren Stil von Klassen in Python (die vom Objekt abgeleiteten) zu verwenden. Um mich mit ihnen vertraut zu machen, versuche ich, eine Klasse zu definieren, die eine Anzahl von Klasseninstanzen als Attribute aufweist, wobei jede dieser Klasseninstanzen eine andere Art von Daten beschreibt, z. 1d Listen, 2d Arrays, Skalare etc. Grundsätzlich möchte ich schreiben können

%Vor%

Dabei ist data_type eine Klasseninstanz, die eine Sammlung von Variablen beschreibt. Unten ist mein erster Versuch dies zu implementieren, indem ich nur eine profiles_1d Instanz und eher generische Namen verwende:

%Vor%

Ist der obige Code in etwa ein angemessener Weg, um dieses Problem anzugehen? Die Beispiele, die ich bei der Verwendung von property gesehen habe, setzen einfach den Wert einer Variablen. Hier benötige ich meine set-Methode, um eine Instanz einer Klasse zu initialisieren. Wenn nicht, wären alle anderen Vorschläge für bessere Möglichkeiten, dies zu implementieren, sehr zu begrüßen.

Außerdem ist die Art, wie ich meine Set-Methode definiere, in Ordnung? Im Allgemeinen definiert die set-Methode, soweit ich es verstehe, was zu tun ist, wenn der Benutzer in diesem Beispiel

tippt %Vor%

Der einzige Weg, wie ich die Attribute der profiles_1d -Instanz mit dem obigen Code korrekt einstellen kann, ist collection.set_profiles([...], y1=[...], ...) einzugeben, aber ich denke, dass ich diese Methode nicht direkt aufrufen sollte. Idealerweise würde ich collection.profiles = ([...], y1=[...], ...) eingeben: Ist das korrekt / möglich?

Endlich habe ich viele Dekorateure erwähnt, die sehr auf den neuen Klassenstil achten, aber davon weiß ich wenig. Ist der Einsatz von Dekorateuren hier angebracht? Ist das etwas, worüber ich für dieses Problem mehr wissen sollte?

    
Chris 11.08.2011, 11:18
quelle

2 Antworten

10

Erstens, es ist gut, dass Sie neue Klassen lernen. Sie haben viele Vorteile.

Der moderne Weg, Eigenschaften in Python zu erstellen, ist:

%Vor%

setze dann profiles , indem du

tust %Vor%

Beachten Sie, dass alle drei Methoden den gleichen Namen haben.

Dies wird normalerweise nicht gemacht; Entweder übergeben sie die Attribute an collection s Konstruktor oder lassen sie die profiles_1d selbst erstellen und dann collections.profiles = myprofiles1d oder übergeben sie an den Konstruktor.

Wenn Sie möchten, dass das Attribut den Zugriff auf sich selbst verwaltet anstelle der Klasse, die den Zugriff auf das Attribut verwaltet, machen Sie das Attribut zu einer Klasse mit einem Deskriptor. Tun Sie dies, wenn Sie, anders als im Beispiel oben, die Daten tatsächlich innerhalb des Attributs (anstelle einer anderen, faux-privaten Instanzvariablen) haben möchten. Außerdem ist es gut, wenn Sie dieselbe Eigenschaft immer wieder verwenden möchten - machen Sie sie zu einem Deskriptor, und Sie müssen den Code nicht mehrmals schreiben oder eine Basisklasse verwenden.

Ich mag die Seite von @ S.Lott - Building Skills in Pythons Attributen , Eigenschaften und Deskriptoren .

    
agf 11.08.2011, 12:01
quelle
1

Bei der Erstellung von property s (oder anderen Deskriptoren), die andere Instanzmethoden aufrufen müssen, muss die Benennungskonvention diesen Methoden ein _ voranstellen; Ihre Namen wären also _get_profiles , _set_profiles und _del_profiles .

In Python 2.6+ ist jede Eigenschaft auch ein Dekorator, so dass Sie die (sonst nutzlosen) _name -Methoden nicht erstellen müssen:

%Vor%

Es sieht so aus, als ob Ihr Code versucht, profiles für die Klasse anstatt der Instanzen zu setzen - wenn dies der Fall ist, werden die Eigenschaften der Klasse nicht funktionieren, da collections.profiles mit einem profiles_1d -Objekt außer Kraft gesetzt würde. die Eigenschaft zu vergewaltigen ... Wenn das wirklich das ist, was du willst, musst du eine Metaklasse machen und stattdessen die Eigenschaft dort einfügen.

Hoffentlich sprichst du über Instanzen, also würde die Klasse wie folgt aussehen:

%Vor%

und dann würden Sie etwas wie:

tun %Vor%

Ein paar Dinge zu beachten: Die Methode setter wird nur mit zwei Elementen aufgerufen: self und die neue value (deshalb müssen Sie set_profiles1d manuell aufrufen); Bei einer Zuweisung ist die Benennung von Schlüsselwörtern keine Option (das funktioniert nur in Funktionsaufrufen, was eine Zuweisung nicht ist). Wenn es für Sie Sinn ergibt, können Sie sich etwas einfallen lassen und etwas wie:

tun %Vor%

und ändern Sie dann die setter zu:

%Vor%

das ist immer noch ziemlich lesbar (obwohl ich die x, y1, y2, y3 Version selbst bevorzuge).

    
Ethan Furman 06.01.2012 19:54
quelle