Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

classe parent

29 réponses
Avatar
JB
Bonjour a tous...

Peut etre une question de newbie mais je n'ai pas reussi à trouver de
réponse, surement que j'utilise les mauvais termes...

Voila j'ai une classe A qui a comme attribut une classe B

class A:
def __init__(self):
self.valeur="test A"
self.b=B()
class B:
def __init__(self):
self.valeur="test B"

comment faire pour récupérer A.valeur directement depuis B ?

faut il forcement, lors de l'instanciation de B, indiquer un lien vers A
? (self.B.A = self par exemple)

ou y a t il un moyen plus classe de trouver la classe 'parente' de B
directement?

voila, je suis sur que Python propose une solution pythonesque pour ca ;)

merci a tous

a+

Julien

10 réponses

1 2 3
Avatar
Jerome
Bonjour a tous...


bonjour


Peut etre une question de newbie mais je n'ai pas reussi à trouver de
réponse, surement que j'utilise les mauvais termes...


effectivement, tu n'as pas de lien d'héritage entre tes classes donc pas
de classe parente.


Voila j'ai une classe A qui a comme attribut une classe B

class A:
def __init__(self):
self.valeur="test A"
self.b=B()
class B:
def __init__(self):
self.valeur="test B"


class A(objet):
class B(objet):


comment faire pour récupérer A.valeur directement depuis B ?

faut il forcement, lors de l'instanciation de B, indiquer un lien vers A
? (self.B.A = self par exemple)

ou y a t il un moyen plus classe de trouver la classe 'parente' de B
directement?


A n'est pas la classe parente de B. Tu as à la rigueur un lien
d'aggrégation entre les classes mais pas un lien d'héritage, tu ne peux
pas accéder à la classe A depuis la classe B.


voila, je suis sur que Python propose une solution pythonesque pour ca ;)


En général, ce genre de problèmes peuvent être le signe d'une mauvaise
modélisation.


merci a tous

a+

Julien


Avatar
kib
Comme ceci peut-être ...

class A(object):
def __init__(self):
self.valeur = "test A"
self.b = B(self)

class B(object):
def __init__(self,parent):
self.parent = parent
self.valeur = "test B"

def getParentValue(self):
return self.parent.valeur

a = A()
print a.b.getParentValue() --> renvoie "test A"
Avatar
Eric Brunel
On Tue, 06 Nov 2007 12:12:26 +0100, JB wrote:
Bonjour a tous...

Peut etre une question de newbie mais je n'ai pas reussi à trouver de
réponse, surement que j'utilise les mauvais termes...


Vu ce qui suit: euh..., oui...

Voila j'ai une classe A qui a comme attribut une classe B

class A:
def __init__(self):
self.valeur="test A"
self.b=B()
class B:
def __init__(self):
self.valeur="test B"


C'est mal parti: tes classes n'ont aucun attribut. Ce sont leurs instances
qui auront des attributs, pas les classes elles-mêmes. Tu sembles mélanger
les notions de classe et d'objet. Es-tu au point là-dessus?

comment faire pour récupérer A.valeur directement depuis B ?


A.valeur n'existe pas. Si a est une instance de A, alors a.valeur existe,
mais il n'y a pas de A.valeur.


faut il forcement, lors de l'instanciation de B, indiquer un lien vers A
? (self.B.A = self par exemple)


On peut plus ou moins dire ça comme ça, mais certainement pas faire ce que
tu indiques là... Si l'instance de B a besoin de manipuler l'instance de A
à partir de laquelle elle a été créée, voilà ce que je ferais:

class A(object):
def __init__(self):
self.valeur = "test A"
self.b = B(self)

class B(object):
def __init__(self, a_parent):
self.a_parent = a_parent
self.valeur = "test B"

Dans ce cas, dans une instance de B, tu pourras accéder à la valeur de
l'instance parente via self.a_parent.valeur.

ou y a t il un moyen plus classe de trouver la classe 'parente' de B
directement?


Encore une fois, tu mélanges les classes et les objets. On parle de classe
parente quand il y a spécialisation ("héritage"); ici, personne ne
spécialise personne, donc il n'y aucune classe parente.

HTH
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"

Avatar
JB
effectivement, tu n'as pas de lien d'héritage entre tes classes donc pas
de classe parente.
A n'est pas la classe parente de B. Tu as à la rigueur un lien
d'aggrégation entre les classes mais pas un lien d'héritage, tu ne peux
pas accéder à la classe A depuis la classe B.


ok, c'est clair, en effet je m'exprime mal c'est un simple lien
d'aggrégation entre deux classes 100% distinctes

En général, ce genre de problèmes peuvent être le signe d'une mauvaise modélisation.


j'ai une classe globale, qui contient des variables (attributs) et
certains de ces attributs sont d'autres classes.

ex :

class MonServeur:
def __init__(self):
self.params = {}
self.http_server = HttpServer()

comment faire pour que http_server puisse utiliser des parametres
définis par ma classe 'principale' ? sinon comment faire autrement ?

Merci pour les precisions

Julien

Avatar
JB
Comme ceci peut-être ...

class A(object):
def __init__(self):
self.valeur = "test A"
self.b = B(self)

class B(object):
def __init__(self,parent):
self.parent = parent
self.valeur = "test B"

def getParentValue(self):
return self.parent.valeur

a = A()
print a.b.getParentValue() --> renvoie "test A"


Merci, c'est ce que je fais actuellement mais je me dis que python nous
apporte peut etre une solution plus stylée avec inspect ou un truc du
style mais apparemment non ;(

Julien.

Avatar
JB
C'est mal parti: tes classes n'ont aucun attribut. Ce sont leurs
instances qui auront des attributs, pas les classes elles-mêmes. Tu
sembles mélanger les notions de classe et d'objet. Es-tu au point
là-dessus?


Je pense être plus au point en codant qu'en l'expliquant lol ;)

On peut plus ou moins dire ça comme ça, mais certainement pas faire ce
que tu indiques là... Si l'instance de B a besoin de manipuler
l'instance de A à partir de laquelle elle a été créée, voilà ce que je
ferais:

class A(object):
def __init__(self):
self.valeur = "test A"
self.b = B(self)

class B(object):
def __init__(self, a_parent):
self.a_parent = a_parent
self.valeur = "test B"

Dans ce cas, dans une instance de B, tu pourras accéder à la valeur de
l'instance parente via self.a_parent.valeur.


Ok c'est ce que je fais actuellement mais je me demandais s'il n'y avait
un truc magique en python comme on en trouve souvent ;)

j'imaginais un __parentclass__ ou quelque chose comme ca mais je dois
rever eveillé

merci pour vos precisions

Julien

Avatar
Jerome
effectivement, tu n'as pas de lien d'héritage entre tes classes donc
pas de classe parente.
A n'est pas la classe parente de B. Tu as à la rigueur un lien
d'aggrégation entre les classes mais pas un lien d'héritage, tu ne
peux pas accéder à la classe A depuis la classe B.


ok, c'est clair, en effet je m'exprime mal c'est un simple lien
d'aggrégation entre deux classes 100% distinctes

En général, ce genre de problèmes peuvent être le signe d'une
mauvaise modélisation.


j'ai une classe globale, qui contient des variables (attributs) et
certains de ces attributs sont d'autres classes.


"certains de ces attributs sont d'autres classes"
=> d'autres instances de classes j'imagine ?

Si oui c'est un peu le cas de tous les attributs dans un langage objet.


ex :

class MonServeur:
def __init__(self):
self.params = {}
self.http_server = HttpServer()

comment faire pour que http_server puisse utiliser des parametres
définis par ma classe 'principale' ? sinon comment faire autrement ?


Ta classe principale est MonServeur c'est ça ?

Je dirais naïvement au vu de ces informations qu'il est possible que ton
serveur soit une spécialisation d'un serveur Http auquel cas tu peux
définir un vrai lien d'héritage

class MonServeur(HttpServer):

Sinon, à la création de l'instance self.http_server, tu peux passer au
constructeur les paramètres dont tu auras besoin pour configurer ton
serveur Http.

self.http_server = HttpServer(self.params.port, self.params.host)





Merci pour les precisions

Julien



Avatar
Bruno Desthuilliers

C'est mal parti: tes classes n'ont aucun attribut. Ce sont leurs
instances qui auront des attributs, pas les classes elles-mêmes. Tu
sembles mélanger les notions de classe et d'objet. Es-tu au point
là-dessus?



Je pense être plus au point en codant qu'en l'expliquant lol ;)

On peut plus ou moins dire ça comme ça, mais certainement pas faire ce
que tu indiques là... Si l'instance de B a besoin de manipuler
l'instance de A à partir de laquelle elle a été créée, voilà ce que je
ferais:

class A(object):
def __init__(self):
self.valeur = "test A"
self.b = B(self)

class B(object):
def __init__(self, a_parent):
self.a_parent = a_parent
self.valeur = "test B"

Dans ce cas, dans une instance de B, tu pourras accéder à la valeur de
l'instance parente via self.a_parent.valeur.



NB: avec toutefois le problème qu'on a une référence cyclique, qui sera
donc plus coûteuse à collecter - bref, à éviter s'il y a beaucoup
d'instances de A... Si les instances de B "appartiennent" réellement aux
instances de A (=> si leur cycle de vie est géré par l'instance de A),
alors une solution serait d'utiliser des références faibles:

import weakref



class A(object):
def __init__(self):
self.valeur = "test A"
self.b = B(self)

class B(object):
# on utilise un attribut calculé
# pour gérer la référence faible
@apply
def parent():
def fget(self):
# on déréférence
p = self._parent()
if p is None:
# ne devrait pas arriver
raise AttributeError("bouh, je suis orphelin")
return p
def fset(self, val):
self._parent = weakref.ref(val)
return property(**locals())

def __init__(self, parent):
self.parent = parent
self.valeur = "test B"


Mais bon... Comme le fait remarquer Jérôme, une référence cyclique,
c'est souvent (nb: donc pas _toujours_ !-) le signe d'un problème de
conception.



Ok c'est ce que je fais actuellement mais je me demandais s'il n'y avait
un truc magique en python comme on en trouve souvent ;)

j'imaginais un __parentclass__


Là encore, pb de terminologie - il ne s'agit pas d'une classe parente.

ou quelque chose comme ca mais je dois
rever eveillé


Oui, en effet. Sachant qu'en Python, tout est objet (fonctions, classes
et modules compris), et qu'on accède toujours à un objet par une
référence, qui peut être partagée à tout moment (contrairement par
exemple au C++, où un objet peut totalement contrôler le cycle de vie
d'un autre), je ne vois pas comment ça pourrait être gérable. Imagine:

class A(object):
pass

class B(object):
def __init__(self, a):
self.a = a

a = A()
bs = [B(a) for i in range(10)]

Que devrait renvoyer ton attribut magique pour l'objet référencé par 'a' ?-)


Avatar
Bruno Desthuilliers
(snip)
En général, ce genre de problèmes peuvent être le signe d'une
mauvaise modélisation.



j'ai une classe globale,


???

qui contient des variables (attributs)


En Python, il n'y a pas de réelle notion de "contenant". Dans le sens où
une variable n'est pas un tag sur une adresse mémoire "contenant" une
valeur, mais un couple nom/référence sur un objet. Une même référence
peut être liée simultanément à plusieurs noms dans plusieurs espaces de
nommages différents. Bref, tout ce qui est "contenu" dans l'objet, ce
sont des références sur d'autres objets - pas ces objets.

et
certains de ces attributs sont d'autres classes.


cf plus bas...

ex :

class MonServeur:


Sauf raison majeure, utilise de préférence le "nouveau" (si l'on peut
dire - il date de la 2.3 SJMSB) modèle objet:

class MonServeur(object):

def __init__(self):
self.params = {}
self.http_server = HttpServer()



Cet exemple ne correspond pas à la description que tu fais plus haut. Le
seul attribut propre de la *classe* MonServeur est la fonction __init__
- qui n'est pas une classe. Et les attributs *d'instance* ne sont pas
des classes, mais une instance de dict et une instance de HttpServer. Ne
va pas croire que les problèmes de terminologie sont sans importance, on
ne peut pas raisonner clairement dans ce domaine si on se mélange dans
les concepts.

Accessoirement, je te rappelle qu'en Python *tout* est objet (même les
fonctions, les classes et les modules). Que l'objet soit un type builtin
avec une notation littérale ou une instance d'une classe que tu a défini
toi-même n'y change rien.


comment faire pour que http_server puisse utiliser des parametres
définis par ma classe 'principale' ?


En les lui passant ?

sinon comment faire autrement ?


Impossible de répondre utilement sans connaissance de la classe
HttpServer, dont tu ne précises ni la provenance ni l'API.


Avatar
JB
"certains de ces attributs sont d'autres classes"
=> d'autres instances de classes j'imagine ?
Si oui c'est un peu le cas de tous les attributs dans un langage objet.


Oui, bien dit, surtout en python ;)

Ta classe principale est MonServeur c'est ça ?

Je dirais naïvement au vu de ces informations qu'il est possible que ton
serveur soit une spécialisation d'un serveur Http auquel cas tu peux
définir un vrai lien d'héritage

class MonServeur(HttpServer):

Sinon, à la création de l'instance self.http_server, tu peux passer au
constructeur les paramètres dont tu auras besoin pour configurer ton
serveur Http.

self.http_server = HttpServer(self.params.port, self.params.host)


Beh en fait MonServeur fait serveur HTTP mais aussi plusieurs autres
choses dont un client Jabber et d'autres classes donc je voudrai créer
une classe principale qui regroupe toutes les fonctions (gérées par
d'autres classes) mais qui regroupe les infos utiles, par exemple un
dico de configuration qui pourrait etre partagé entre les différentes
classes

1 2 3