Définition attribut classe parente
RésoluSalut à tous, une question existentielle.
J'ai quelques classes héritant d'une même classe mère (pas un singleton), cette classe mère ne doit donc pas être instanciée directement, uniquement via les classes en héritant.
Maintenant, cette classe mère à besoin de l'instance d'une autre classe, qui lui sert à travailler elle-même, mais aussi les classes dérivées.
D'après-moi, il n'y a pas 36 solutions, soit en définissant une variable de classe dans la classe mère, et jeter une erreur si non définie :
class Outils: def __str__(self): return 'outils !' class Maman: outils = None def __init__(self): if not isinstance(self.outils, Outils): raise AttributeError('outils non défini ou invalide') class Bob(Maman): pass try: bob = Bob() except Exception as e: print(e) Maman.outils = Outils() bob = Bob() print(bob.outils)
Cela ne me convient pas trop, puisque cela oblige à avoir accès à Maman. On pourrait faire autrement en permettant d'utiliser un argument optionnel dans la classe Bob qui devra être défini via la 1ère instance de Bob.
class Outils: def __str__(self): return 'outils !' class Maman: _outils = None def __init__(self, outils=None): if not isinstance(self._outils, Outils): if not isinstance(outils, Outils): raise AttributeError('outils doit être défini une 1ère fois') Maman._outils = outils self._outils = outils class Bob(Maman): def __init__(self, outils=None): super().__init__(outils) try: bob = Bob() except Exception as e: print(e) outils = Outils() bob = Bob(outils) bob2 = Bob() print(bob2.outils)
Mais idem, je trouve que cela peut être compliqué lorsque les instances de Bob peuvent être créées partout dans une application et parfois pas dans le même ordre.
Une dernière solution qui pour moi serait la meilleure est d'instancier Outils dans un module réservé à cet effet, par ex. communs.py et que l'application instancie Outils dans ce fichier commun, ainsi Maman devrait simplement aller chercher cet objet dans le module commun.
Le seul bémol avec cette approche est que tout le monde peut avoir accès à cet objet Outils.
Comment faites-vous (feriez-vous) cela ?
Avez-vous une autre façon de faire ?
- Définition attribut classe parente
- Attribut changer - Télécharger - Divers Utilitaires
- Classe ram - Guide
- Bluetooth mercedes classe a - Forum Autoradio
- Dans le code de la page, modifiez la couleur de fond de la classe .pix. - Forum Réseaux sociaux
- Sti2d classe poubelle - Forum Programmation
4 réponses
bonjour,
C'est la classe Maman qui a besoin d'une l'instance de Outil, ou bien chaque instance de Maman qui en a besoin?
Dans le premier cas:
class Outils: def __init__(self): print("un nouvel outil a été créé",self) class Maman: _outils = Outils() print("un outil créé par maman") def __init__(self): print("nouvelle maman",self,self._outils) class Bob(Maman): pass print("start") bob1=Bob() bob2=Bob()
Pourquoi écris-tu que ta première solution "oblige à avoir accès à Maman"?
Tu peux, en ligne 19:
Bob.outils = Outils()
Bonjour
si je comprends bien ton besoin, Outils a tout intérêt à être un singleton.
Ainsi tu peux l'appeler comme yg_be l'a proposé dans son message #1
S'il a déjà été instancié par un autre objet qui en avait besoin, tu récupèreras l'instance sinon tu la créera
Bonjour,
Personnellement j'ai du mal à comprendre ce que tu cherches à faire. Peux-tu clarifier ton besoin ?
Maintenant, cette classe mère à besoin de l'instance d'une autre classe, qui lui sert à travailler elle-même, mais aussi les classes dérivées.
Peux-tu clarifier ? Est-ce qu'un bon vieil héritage ne suffit pas ?
J'ai quelques classes héritant d'une même classe mère (pas un singleton), cette classe mère ne doit donc pas être instanciée directement, uniquement via les classes en héritant.
Pourquoi "donc ne doit pas être instanciée directement" ? Essayes-tu de faire une classe abstraite ?
Comme le dit Whismeril #8, en toute logique Outils devrait être un Singleton (cf #5). Y a-t'il une raison qui t'interdit d'en faire un singleton, et si oui laquelle ? Car à partir du moment où c'est un singleton, tu "l'instancies" dans les méthodes où tu en as besoin et tu n'as aucune raison {d'en hériter | de la mémoriser en attribut de classe/instance | de la passer en paramètre}. C'est l'un des intérêts des singletons.
Le seul cas pratique que je vois où une classe mère peut avoir besoin de connaître ses classes filles, c'est quand tu implémentes des plugins sous forme de classe et que tu veux que ton framework supporte des plugins tiers. Est-ce ton cas ? Si oui, je t'invite à regarder ce lien.
Bonne chance
Bonjour,
Juste pour clarifier, les trois notions ci-dessous sont distinctes, répondent à des besoins différents, et son non-exclusive.
- Un singleton est une manière de garantir qu'une classe ne peut être qu'instanciée qu'une seule fois (voir ici). Si on l'instancie plusieurs fois, on obtient une référence sur la même instance.
- Une classe abstraite implémente un sous-ensemble de ses méthodes ; tant qu'une classe possède au moins une méthode abstraite, la classe ne doit pas être instanciée, car si on appelle une méthode abstraite (non implémentée) le programme lèvera une exception. Certains langages (comme le C++ et le Java) interdisent d'instancier des classes abstraites.
- Par défaut, une classe mère n'a aucune idée de quelles sont ses classes filles. Toutefois, Python permet au travers de la méthode __init_subclass__ (voir ici) d'enregistrer dans une classe mère ses classes filles, ce n'est donc pas le comportement par défaut.
Dans ton cas tu n'en as probablement besoin que des deux premières notions...
Salut, cela aurait pu être faisable, mais outils doit être aussi utilisé ailleurs (j'aurais dû le préciser), c'est pour cela que dans le très gros résumé que j'en ai fait, Outils est instancié hors de ces classes et que l'instanciation a de plus, besoin de paramètres qui ne sont pas connus par ces classes.
Merci de ta proposition =)
Tu as plusieurs instances de Outils()?
Peut-être manque-t-il une classe plus globale.
Non, il n'y a qu'un unique objet Outils utilisé par plusieurs classes, pour cela que ma 3ème idée était de partager cet objet via un module dédié exclusivement à cela et qui simplifie vraiment la chose.
Oui, pourquoi pas ajouter un niveau supérieur, genre une classe singleton qui serait instanciée dans le main, je vais creuser dans ce sens.
Pourquoi instancier Outils?
Outils est une classe comportant beaucoup de méthodes et données diverses, ce n'est pas juste un simple container, sinon en effet, ce serait bien plus simple =)