Dies ist ein weiterer Fall von pylintBlindregeln.
"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 attrsund ist ein Standardbibliotheksmechanismus ("Batterien enthalten") ohne zusätzliche Abhängigkeiten, außer Python 3.7+.
Rest der vorherigen Antwort
NamedTupleist 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 NamedTupleMuster "Klasse abgeleitet von " überprüfen . Python 2 - namedtupleserstellt 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 = fooanstatt 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). .