Problème
Je travaille sur un projet Python dont la classe principale est un peu " God Object ". Il y a tellement d'attributs et de méthodes!
Je veux refactoriser la classe.
Jusque là…
Pour la première étape, je veux faire quelque chose de relativement simple; mais quand j'ai essayé l'approche la plus simple, elle a cassé certains tests et exemples existants.
Fondamentalement, la classe a une longue liste d'attributs - mais je peux clairement les regarder et penser, "Ces 5 attributs sont liés ... Ces 8 sont également liés ... et puis il y a le reste."
getattr
Je voulais simplement regrouper les attributs associés dans une classe d'aide de type dict. J'avais le sentiment que ce __getattr__
serait idéal pour le travail. J'ai donc déplacé les attributs dans une classe distincte et, bien sûr, j'ai __getattr__
parfaitement bien fonctionné sa magie…
Au début .
Mais j'ai ensuite essayé d'exécuter l'un des exemples. L'exemple de sous-classe tente de définir directement l'un de ces attributs (au niveau de la classe ). Mais comme l'attribut n'était plus «physiquement localisé» dans la classe parente, j'ai eu une erreur en disant que l'attribut n'existait pas.
@propriété
J'ai ensuite lu sur le @property
décorateur. Mais j'ai également lu que cela crée des problèmes pour les sous-classes qui veulent faire self.x = blah
quand x
est une propriété de la classe parente.
Voulu
- Demandez à tout le code client de continuer à fonctionner
self.whatever
, même si lawhatever
propriété du parent n'est pas «physiquement située» dans la classe (ou l'instance) elle-même. - Regroupez les attributs associés dans des conteneurs de type dict.
- Réduisez l'extrême bruit du code dans la classe principale.
Par exemple, je ne veux pas simplement changer cela:
larry = 2
curly = 'abcd'
moe = self.doh()
En cela:
larry = something_else('larry')
curly = something_else('curly')
moe = yet_another_thing.moe()
… Parce que c'est encore bruyant. Bien que cela transforme avec succès un simple attribut en quelque chose qui peut gérer les données, l'original avait 3 variables et la version modifiée a toujours 3 variables.
Cependant, je serais bien avec quelque chose comme ça:
stooges = Stooges()
Et si une recherche self.larry
échoue, quelque chose vérifierait stooges
et verrait s'il larry
existe. (Mais cela doit aussi fonctionner si une sous-classe essaie de faire larry = 'blah'
au niveau de la classe.)
Sommaire
- Vous souhaitez remplacer des groupes d'attributs associés dans une classe parente par un seul attribut qui stocke toutes les données ailleurs
- Vous voulez travailler avec du code client existant qui utilise (par exemple)
larry = 'blah'
au niveau de la classe - Vous souhaitez continuer à autoriser les sous-classes à étendre, remplacer et modifier ces attributs refactorisés sans savoir que quelque chose a changé
Est-ce possible? Ou suis-je en train d'aboyer le mauvais arbre?