Dies ist ein weiterer Fall von pylint
Blindregeln.
"Klassen sollen keine Daten speichern" - dies ist eine falsche Aussage. Wörterbücher sind nicht für alles gut. Ein Datenelement einer Klasse ist etwas Sinnvolles, ein Wörterbuchelement ist etwas Optionales. Beweis: Sie können tun dictionary.get('key', DEFAULT_VALUE)
, um ein zu verhindern KeyError
, aber es gibt keine einfache __getattr__
mit Standard.
BEARBEITEN - empfohlene Methoden zur Verwendung von Strukturen
Ich muss meine Antwort aktualisieren. Im Moment - wenn Sie eine benötigen struct
, haben Sie zwei großartige Möglichkeiten:
a) Einfach benutzen attrs
Dies ist eine Bibliothek dafür:
https://www.attrs.org/en/stable/
import attr
@attr.s
class MyClass(object): # or just MyClass: for Python 3
foo = attr.ib()
bar = attr.ib()
Was Sie zusätzlich erhalten: Schreiben von Konstruktoren, Standardwerten, Validierung, __repr__
schreibgeschützten Objekten (zu ersetzen namedtuples
, auch in Python 2) und mehr.
b) Verwenden Sie dataclasses
(Py 3.7+)
Nach dem Kommentar von hwjp empfehle ich außerdem dataclasses
:
https://docs.python.org/3/library/dataclasses.html
Dies ist fast so gut wie attrs
und ist ein Standardbibliotheksmechanismus ("Batterien enthalten") ohne zusätzliche Abhängigkeiten, außer Python 3.7+.
Rest der vorherigen Antwort
NamedTuple
ist nicht großartig - besonders vor Python 3 typing.NamedTuple
:
https://docs.python.org/3/library/typing.html#typing.NamedTuple
- Sie sollten auf jeden Fall das NamedTuple
Muster "Klasse abgeleitet von " überprüfen . Python 2 - namedtuples
erstellt aus String-Beschreibungen - ist hässlich, schlecht und "Programmieren in String-Literalen" dumm.
Ich stimme den beiden aktuellen Antworten zu ("Überlegen Sie, etwas anderes zu verwenden, aber Pylint ist nicht immer richtig" - die akzeptierte und "Verwenden Sie einen Kommentar zur Unterdrückung von Pylint"), aber ich habe meinen eigenen Vorschlag.
Lassen Sie mich noch einmal darauf hinweisen: Einige Klassen dienen nur zum Speichern von Daten.
Jetzt die Option auch zu berücksichtigen - use property
-ies.
class MyClass(object):
def __init__(self, foo, bar):
self._foo = foo
self._bar = bar
@property
def foo(self):
return self._foo
@property
def bar(self):
return self._bar
Oben haben Sie schreibgeschützte Eigenschaften, die für Value Object in Ordnung sind (z. B. wie bei Domain Driven Design), aber Sie können auch Setter bereitstellen. Auf diese Weise kann Ihre Klasse beispielsweise die Verantwortung für die Felder übernehmen, über die Sie verfügen Um eine Validierung usw. durchzuführen (wenn Sie Setter haben, können Sie diese im Konstruktor zuweisen, dh self.foo = foo
anstatt direkt self._foo = foo
, aber vorsichtig, die Setter können davon ausgehen, dass andere Felder bereits initialisiert sind, und dann benötigen Sie eine benutzerdefinierte Validierung im Konstruktor). .