Das Problem ist das man eingeschränkt wird was man an den Klassen noch ändern darf/kann ohne das es zu Problemen kommt wenn man nach Änderungen ältere Pickle-Dateien wieder einlesen will. Wenn man die Klasse umbenennt oder in ein anderes Modul verschiebt kann man keine Exemplare davon mehr entpickeln, weil die Klasse nicht mehr gefunden werden kann. Die Struktur der Klasse darf man dann auch nicht mehr verändern.
Pickle ist gut und nützlich um kurzfristig Python-Objekte zu serialisieren oder wenn es kein Problem ist, wenn das deserialisieren nicht mehr klappt. Zum Beispiel wenn man Objekte zu einem anderen Prozess übertragen möchte oder berechnete Werte extern Cachen möchte, die man zur Not einfach neu berechnen kann.
Für längerfristige Speicherung sollte man explizit Code schreiben der die Daten in einem standardisierten Format (de)serialisiert. Am besten auch mit einer Versionsnummer versehen, so das man bei Änderungen am Format erkennt in welcher Version die gespeicherten Daten vorliegen und man entsprechend auch unterschiedlichen Code für die Versionen haben kann, also auch alte Daten noch einlesen kann, sofern die Änderungen nicht so stark sind, das man das nicht automatisch konvertieren kann, oder zumindest mit ein paar Rückfragen an den Benutzer.
”Pythonisch” ist es möglichst einfach und verständlich zu halten. Properties einzusetzen wo es nur geht gehört da sicher nicht dazu, denn das ist ganz viel Code der nichts macht. Wenn Du triviale Getter und Setter hast, dann bringt das doch effektiv gar keinen Unterschied dazu einfach die Attribute öffentlich zu machen, denn das sind sie effektiv ja. Wenn man für ein Attribut einen Getter und einen Setter hat, dann ist da nichts gekapselt. Wenn man das dann auch noch als Property verfügbar macht, dann ändert sich ja nicht einmal am Code der das benutzt etwas. Das ist einfach nur viel Schreibarbeit für *nichts*.
klein_mit_unterstrichen betrifft übrigens auch Methodennamen.
So wie Du `property` verwendest macht das heute auch niemand mehr. Seit dem es die Dekoratorsyntax gibt, schreibt man das so:
Code: Alles auswählen
@property
def some_value(self):
return self._some_value + 1
@some_value.setter
def some_value(self, value):
self._some_value = value - 1
Ja, Datenkapselung ist eine gute Idee, aber eben nur da wo es Sinn macht und nochmal: Wenn man triviale Getter/Setter hat, dann ist da nix gekaspelt. Weil es effektiv ja überhaupt gar keinen Unterschied gibt ob so ein Wert nun als Attribut vorliegt, oder ob man den kleinen Umweg über Methoden geht – man kann an den Wert von aussen problemlos heran kommen und man kann ihn problemlos setzen.
Und in Python ist man generell nicht so paranoid alles verbieten/erzwingen zu wollen. Man geht von einem mündigen Programmierer aus, der weiss was er tut, und mit den Konsequenzen seines Handelns klar kommt. Man könnte beispielweise für `score` ein reines `get`-Property schreiben und eine `increase_score()` Methode, damit auch ja niemand etwas anderes machen kann als `score` um 1 zu erhöhen. Oder man lässt `score` öffentlich und bietet vielleicht eine `increase_score()` Methode an – oder auch nicht.
Mein Beispiel ist doch nicht wirklich fortgeschritten. Ich finde das im Gegenteil sehr einfach, und es unterscheidet sich bei dem was da steht auch kaum von der ebenfalls einfachen Klasse die Sirius3 geschrieben hat. Der Vorteil vom `attr`-Modul gegenüber so einfachen selbst geschriebenen Klassen ist, das man neben der Schreibarbeit die man sich in der `__init__()` spart, das man auch eine `__repr__()` und die ganzen Vergleichsfunktionen frei Haus bekommt: https://www.attrs.org/en/stable/why.htm ... en-classes