C'est un autre cas des règles aveugles de Pylint.
"Les classes ne sont pas destinées à stocker des données" - c'est une fausse affirmation. Les dictionnaires ne sont pas bons pour tout. Un membre de données d'une classe est quelque chose de significatif, un élément de dictionnaire est quelque chose d'optionnel. Preuve : vous pouvez faire dictionary.get('key', DEFAULT_VALUE)
pour éviter un KeyError
mais il n'y a pas de solution simple __getattr__
par défaut.
Méthodes recommandées pour l'utilisation des structs
Je dois mettre à jour ma réponse. Pour l'instant - si vous avez besoin d'un struct
vous avez deux grandes options :
a) Utilisez simplement attrs
Il existe une bibliothèque pour cela :
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()
Ce que vous obtenez en plus : ne pas écrire de constructeurs, valeurs par défaut, validation, __repr__
des objets en lecture seule (pour remplacer namedtuples
(même en Python 2) et plus encore.
b) Utiliser dataclasses
(Py 3.7+)
Suite au commentaire de hwjp, je recommande aussi dataclasses
:
https://docs.python.org/3/library/dataclasses.html
C'est presque aussi bien que attrs
et est un mécanisme de bibliothèque standard ("batteries incluses"), sans aucune dépendance supplémentaire, à l'exception de Python 3.7+.
Le reste de la réponse précédente
NamedTuple
n'est pas génial - surtout avant l'introduction de la fonction typing.NamedTuple
: https://docs.python.org/3/library/typing.html#typing.NamedTuple
- vous devez absolument vérifier la "classe dérivée de
NamedTuple
" modèle. Python 2 - namedtuples
créées à partir de descriptions de chaînes de caractères - est laid, mauvais et stupide pour la "programmation à l'intérieur des chaînes de caractères".
Je suis d'accord avec les deux réponses actuelles ("envisagez d'utiliser autre chose, mais Pylint n'a pas toujours raison" - la réponse acceptée, et "utilisez Pylint pour supprimer les commentaires"), mais j'ai ma propre suggestion.
Permettez-moi de le souligner une fois de plus : Certains cours sont destinés juste pour stocker des données.
Maintenant, l'option pour également envisager - utiliser property
- .
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
Ci-dessus, vous avez des propriétés en lecture seule, ce qui est correct pour les Value Objects (comme ceux de Domain Driven Design), mais vous pouvez également fournir des setters - de cette façon, votre classe sera en mesure de prendre la responsabilité des champs que vous avez - par exemple pour faire de la validation, etc, self.foo = foo
au lieu d'un direct self._foo = foo
(mais attention, les setters peuvent supposer que d'autres champs sont déjà initialisés, et il faut alors une validation personnalisée dans le constructeur).