Classe Python et attributs de module
Je suis intéressé par une discussion sur les attributs de classe en Python. Par exemple, ce qui est un bon cas d'utilisation pour les attributs de classe? Pour la plupart, je ne peux pas venir avec un cas où un attribut de classe est préférable à l'utilisation d'un module attribut de niveau. Si cela est vrai, alors pourquoi les avoir autour?
Le problème que j'ai avec eux, c'est que c'est presque trop facile de tabasser un attribut de classe de la valeur par erreur, et puis votre "global" de la valeur s'est transformée en une instance locale de l'attribut.
N'hésitez pas à commenter sur la façon dont vous gérer les situations suivantes:
- Les valeurs des constantes utilisées par une classe et/ou sous-classes. Cela peut inclure le "nombre magique" les clés de dictionnaire ou d'une liste d'indices qui ne changera jamais, mais possible besoin d'un temps d'initialisation.
- Par défaut de l'attribut de classe, que dans de rares occasions, mis à jour pour une instance de la classe.
- Mondial de la structure de données utilisée pour représenter un état interne d'une classe partagée entre toutes les instances.
- Une classe qui initialise un certain nombre d'attributs par défaut, ne sont pas influencés par des arguments du constructeur.
Certains Postes Liés À:
Différence Entre les classes et les Attributs d'Instance
source d'informationauteur
Vous devez vous connecter pour publier un commentaire.
#4:
Je jamais utiliser les attributs de classe pour initialiser l'instance par défaut des attributs (ceux normalement, vous mettez en
__init__
). Par exemple:et jamais:
Pourquoi? Parce que c'est incohérent: il ne fait pas ce que vous voulez, quand vous affecter quoi que ce soit mais un invariant de l'objet:
causes de la liste d'utilisateurs pour être partagés entre tous les objets, qui dans ce cas n'est pas voulu. C'est source de confusion pour les scinder en classe, les attributs et les affectations dans
__init__
selon leur type, donc j'ai toujours les mettre tous dans__init__
que je trouve plus clair de toute façon.Comme pour le reste, en général, je mis à la classe des valeurs à l'intérieur de la classe. Ce n'est pas tellement parce que globales sont "mal"--ils ne sont pas si important que, dans certaines langues, parce qu'ils sont toujours dans l'étendue du module, à moins que le module lui-même est trop grand, mais si le code externe veut y accéder, il est pratique d'avoir toutes les valeurs pertinentes dans un seul endroit. Par exemple, dans module.py:
et puis:
En plus d'avoir des sous-classes pour modifier la valeur (ce qui n'est pas toujours voulu de toute façon), c'est que je n'ai pas à grand-peine à l'importation exception des noms et un tas d'autres choses nécessaires à l'utilisation de l'Obj. "from module import Obj, ObjException, ..." devient lassant rapidement.
Cas 0. Les méthodes de la classe sont juste des attributs de classe. Ce n'est pas seulement une similitude technique - vous pouvez accéder et modifier les méthodes de la classe au moment de l'exécution par l'affectation de callables.
Cas 1. Un module peut facilement définir plusieurs classes. Il est raisonnable d'encapsuler tout sur
class A
enA...
et tout surclass B
enB...
. Par exemple,Cas 2. Cette classe a beaucoup d'attributs par défaut qui peut être modifié dans une instance. Ici, la possibilité de laisser attribut à un "par défaut" est une fonction, pas de bug.
On crée l'instance de NiceDiff d'utiliser l'existant ou légèrement modifiée, mise en forme, mais d'un radiophare d'alignement de piste à une autre langue sous-classes de la classe pour mettre en œuvre certaines fonctions d'une façon fondamentalement différente et redéfinir les constantes:
Votre cas:
self.CONSTANT = ...
donc je ne vois pas un grand risque pour casser.__init__
en fonction de la sémantique.Les attributs de classe sont souvent utilisées pour permettre à annuler les valeurs par défaut dans les sous-classes. Par exemple, BaseHTTPRequestHandler a des constantes de classe sys_version et server_version, le dernier défaut
"BaseHTTP/" + __version__
. SimpleHTTPRequestHandler remplace server_version à"SimpleHTTP/" + __version__
.L'Encapsulation est un bon principe: lorsqu'un attribut est à l'intérieur de la classe à laquelle il se rapporte au lieu d'être dans la portée globale, ce qui donne de l'information supplémentaire pour les personnes lisant le code.
Dans vos situations 1-4, je voudrais donc éviter globals autant que je le peux, et préfèrent utiliser les attributs de classe, qui permettent de bénéficier de l'encapsulation.