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

Module et classe

6 réponses
Avatar
JB
Bonjour à tous

Suite à mon précédent post, Bruno m'a conseillé de créer une classe
'mere' sous forme de module (MonServeur.py) plutot que de classe. ce
module pourrait gérer d'autres classes qui pourraient partager plus
facilement ses variables sans avoir à les passer dans les __init__ .

MonServeur.py (classe 'mere')
import HttpServer
http = HttpServer.HttpServer()
jabber = JabberClient.client()

HttpServer.py
class HttpServer(object):
def __init__(self):
print "http started"

Ou mettre mon __init__ dans MonServeur.py ?
Je dois créer un main.py qui instancie ma classe principale, MonServeur
? Comment initialiser MonServeur ?

main.py
import MonServeur
srv = MonServeur() ?

Les variables 'globales' que les classes devront partager (comme http)
plus haut, pas besoin de specifier self. ?

J'espere avoir été clair ;(

Merci ;)

Julien

6 réponses

Avatar
Pierre Quentel
On 8 nov, 20:10, JB wrote:
Bonjour à tous

Suite à mon précédent post, Bruno m'a conseillé de créer une cl asse
'mere' sous forme de module (MonServeur.py) plutot que de classe. ce
module pourrait gérer d'autres classes qui pourraient partager plus
facilement ses variables sans avoir à les passer dans les __init__ .

MonServeur.py (classe 'mere')
import HttpServer
http = HttpServer.HttpServer()
jabber = JabberClient.client()

HttpServer.py
class HttpServer(object):
def __init__(self):
print "http started"

Ou mettre mon __init__ dans MonServeur.py ?
Je dois créer un main.py qui instancie ma classe principale, MonServeur
? Comment initialiser MonServeur ?

main.py
import MonServeur
srv = MonServeur() ?

Les variables 'globales' que les classes devront partager (comme http)
plus haut, pas besoin de specifier self. ?


Bonjour,

Quand tu fais import MonServeur, le script MonServeur.py est exécuté
et ses variables globales sont initialisées. Dans ton exemple,
l'instance de HttpServer est créée ; tu peux ensuite t'en servir dans
main.py, c'est un attribut du module importé :

srv = MonServeur.http

et de même :

jabber_client = MonServeur.jabber

Comme tu as "import HttpServer" dans MonServeur.py, le nom HttpServer
est dans l'espace de noms du module MonServeur ; dans main.py tu peux
faire référence au module HttpServer par

MonServeur.HttpServer

et on continue : dans ce module HttpServer il y a une classe
HttpServer, que tu peux utiliser dans main.py par

MonServeur.HttpServer.HttpServer

etc, etc

J'espere avoir été clair ;(


Moi aussi !

A+
Pierre

Avatar
Bruno Desthuilliers
Bonjour à tous

Suite à mon précédent post, Bruno m'a conseillé


s/conseillé/suggéré la possibilité, si adapaté au besoin/

!-)

de créer une classe
'mere' sous forme de module (MonServeur.py) plutot que de classe.


Heu... Il me semble que tu continue à avoir un problème avec la
distinction entre classe et objet.

ce
module pourrait gérer d'autres classes qui pourraient partager plus
facilement ses variables sans avoir à les passer dans les __init__ .

MonServeur.py (classe 'mere')


s/classe mere/module/

import HttpServer
http = HttpServer.HttpServer()
jabber = JabberClient.client()

HttpServer.py
class HttpServer(object):
def __init__(self):
print "http started"

Ou mettre mon __init__ dans MonServeur.py ?


Tu n'en n'a pas besoin. Un module est un objet (le processus d'import
retourne une instance de la classe module pour le fichier source
correspondant), dont les attributs sont les noms déclarés au top-level.
Dans ton cas, l'objet MonServeur (qui sera disponible dans tout autre
module important MonServeur) a pour attributs 'http', 'jabber', et
'HttpServeur'.

Je dois créer un main.py qui instancie ma classe principale,


l'instruction import se charge de l'instanciation.

MonServeur
? Comment initialiser MonServeur ?

main.py
import MonServeur
srv = MonServeur() ?


#main.py
import MonServeur as srv # si tu veux l'avoir sous ce nom
print srv.http
print srv.jabber


Les variables 'globales' que les classes devront partager (comme http)
plus haut, pas besoin de specifier self. ?


cd ci-dessus

J'espere avoir été clair ;(


Bin, disons que si tu faisais la distinction entre classe et objet...
Heu, attend, je l'ai déjà dis, ça, non ???

HTH

Avatar
JB
Merci

donc si je comprends bien mon module MonServeur.py pourra lancer mes
différents services (autres classes) et gérer mes variables globales
auxquelles ils pourront avoir access

MonServeur.py
import HttpServer
import JabberClient
config = loadConfig() # une method qui lit un fichier de config (en
xml) et renvoie un dico
http = HttpServer.HttpServer() # init de mon serveur HttpServer perso
jabber = JabberClient.JabberClient() # j'initialise mon client jabber perso

Il ne me reste plus, dans main.py de faire import MonServeur pour
instancier MonServeur. Est-ce une bonne idée de tout lancer à ce moment
la ou vaut il mieux faire une methode MonServeur.init() par exemple ?

Ensuite, dans HttpServer.py, comment alors acceder à MonServeur.config ?

__main__.MonServeur.config ?

c'est moche !!

Autre chose, il me semble avoir vu qu'on peut aussi définir un module
dans un dossier (un dossier + plusieurs fichiers py). dans ce cas, il
faut utiliser un fichier __init__.py pour l'init ? et les fonctions
"spéciales" (__getattr__...) ou les mettre ?

Bin, disons que si tu faisais la distinction entre classe et objet...
Heu, attend, je l'ai déjà dis, ça, non ???


Oui en effet ;) Je dirai : un objet est issu d'une classe ?

Merci :)

Julien

Avatar
Eric Brunel
On Fri, 09 Nov 2007 13:20:27 +0100, JB wrote:
Merci

donc si je comprends bien mon module MonServeur.py pourra lancer mes
différents services (autres classes) et gérer mes variables globales
auxquelles ils pourront avoir access


En gros c'est ça, même si je ne suis pas tout à fait sûr qu'assimiler
simplement un module à une classe singleton ne soit pas au final plus
confusant qu'autre chose... J'aurais plutôt tendance à voir le problème
dans l'autre sens: les classes singleton n'ont été inventées que pour
émuler le comportement des bons vieux modules C avec des variables
statiques et des fonctions. Un module Python ressemble beaucoup plus à un
tel module C qu'à une vraie classe. Typiquement, on va parler de variables
et de fonctions du module, et pas d'attributs ou de méthodes comme pour
une classe. Mais la différence est subtile...

MonServeur.py
import HttpServer
import JabberClient
config = loadConfig() # une method qui lit un fichier de config (en
xml) et renvoie un dico
http = HttpServer.HttpServer() # init de mon serveur HttpServer perso
jabber = JabberClient.JabberClient() # j'initialise mon client jabber
perso

Il ne me reste plus, dans main.py de faire import MonServeur pour
instancier MonServeur.


Attention: l'"instantiation" de MonServeur n'est faite que par le
*premier* import. Ensuite l'"instance" est mise en cache et réutilisée à
chaque nouvel import du même module. Fais le test en mettant un print dans
ton module (directement; pas dans une fonction) et tu verras qu'il n'est
fait qu'une seule fois, même si tu as 250 import du module dans ton appli.

Est-ce une bonne idée de tout lancer à ce moment la ou vaut il mieux
faire une methode MonServeur.init() par exemple ?


Ca ne sert à rien; cf. plus bas.

Ensuite, dans HttpServer.py, comment alors acceder à MonServeur.config ?

__main__.MonServeur.config ?

c'est moche !!


... et ça ne sert à rien. Fais juste un nouveau "import MonServeur" et tu
récupèreras l'"instance" déjà créée.

Autre chose, il me semble avoir vu qu'on peut aussi définir un module
dans un dossier (un dossier + plusieurs fichiers py). dans ce cas, il
faut utiliser un fichier __init__.py pour l'init ? et les fonctions
"spéciales" (__getattr__...) ou les mettre ?


Il n'y a pas de *fonctions* spéciales __getattr__ etc... Il y a des
*méthodes* spéciales __getattr__ etc... Donc, PAQJS, elles ne
fonctionneront pas dans les modules, mais uniquement dans les "vraies"
classes. Si tu en as besoin, il vaut sans doute mieux faire une "vraie"
classe singleton...

Pour le fichier "magique" __init__.py, il est dans la grande majorité des
cas vide. Exemple d'arbo:

mon_package
__init__.py <- vide
toto.py

Si le répertoire parent de mon_package est dans ton PYTHONPATH, tu pourras
faire:

import mon_package.toto

Remarque: n'en abuse pas... Si tu as 300 modules, ça peut servir. Si tu
n'en as que quelques-unes..., fais "import this" et lis la 7ème ligne...
;-)

Bin, disons que si tu faisais la distinction entre classe et objet...
Heu, attend, je l'ai déjà dis, ça, non ???


Oui en effet ;) Je dirai : un objet est issu d'une classe ?


Mmmmouais... Disons qu'une classe est un modèle de construction pour un
objet. Ta classe, c'est le patron que tu trouves dans "Modes & Travaux";
l'objet c'est le tricot, que tu peux refaire autant de fois que tu veux à
partir du même patron.

(O_o mais qu'est-ce que je raconte, moi?!)

Merci :)


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


Avatar
JB

Il ne me reste plus, dans main.py de faire import MonServeur pour
instancier MonServeur.


Attention: l'"instantiation" de MonServeur n'est faite que par le
*premier* import. Ensuite l'"instance" est mise en cache et réutilisée à
chaque nouvel import du même module. Fais le test en mettant un print
dans ton module (directement; pas dans une fonction) et tu verras qu'il
n'est fait qu'une seule fois, même si tu as 250 import du module dans
ton appli.

Ensuite, dans HttpServer.py, comment alors acceder à MonServeur.config ?

... et ça ne sert à rien. Fais juste un nouveau "import MonServeur" et

tu récupèreras l'"instance" déjà créée.


la c'est encore mieux que ce que je pensais, tres pratique du coup ;)

Mmmmouais... Disons qu'une classe est un modèle de construction pour un
objet. Ta classe, c'est le patron que tu trouves dans "Modes & Travaux";
l'objet c'est le tricot, que tu peux refaire autant de fois que tu veux
à partir du même patron.


Voila des exemples concrets ;)

Merci infiniment

Julien


Avatar
Bruno Desthuilliers
On Fri, 09 Nov 2007 13:20:27 +0100, JB wrote:
Merci

donc si je comprends bien mon module MonServeur.py pourra lancer mes
différents services (autres classes) et gérer mes variables globales
auxquelles ils pourront avoir access


En gros c'est ça, même si je ne suis pas tout à fait sûr qu'assimiler
simplement un module à une classe singleton ne soit pas au final plus
confusant qu'autre chose... J'aurais plutôt tendance à voir le problème
dans l'autre sens: les classes singleton n'ont été inventées que pour
émuler le comportement des bons vieux modules C avec des variables
statiques et des fonctions. Un module Python ressemble beaucoup plus à
un tel module C qu'à une vraie classe. Typiquement, on va parler de
variables et de fonctions du module, et pas d'attributs ou de méthodes
comme pour une classe. Mais la différence est subtile...


Techniquement parlant, un module est un objet instance de la classe
module. Il a donc des méthodes (celles définies par la classe module),
et des attributs d'instances, qui sont les noms définis dans le module.
Les règles habituelles de Python s'appliquent quant aux attributs de
type fonction.

(snip)
Il ne me reste plus, dans main.py de faire import MonServeur pour
instancier MonServeur.


Attention: l'"instantiation" de MonServeur n'est faite que par le
*premier* import. Ensuite l'"instance"


Tu peux supprimer les guillements - il y a bien instanciation (mais de
la classe module), et MonServeur est bien une instance.

(snip)

Autre chose, il me semble avoir vu qu'on peut aussi définir un module
dans un dossier (un dossier + plusieurs fichiers py). dans ce cas, il
faut utiliser un fichier __init__.py pour l'init ?



Ca s'appelle un package.

et les fonctions
"spéciales" (__getattr__...) ou les mettre ?


Il n'y a pas de *fonctions* spéciales __getattr__ etc... Il y a des
*méthodes* spéciales __getattr__ etc...


Lesquelles sont des attributs de classe, pas d'instance. Il n'y a donc
pas moyen d'intervenir à ce niveau là.

(snip)

Bin, disons que si tu faisais la distinction entre classe et objet...
Heu, attend, je l'ai déjà dis, ça, non ???


Oui en effet ;) Je dirai : un objet est issu d'une classe ?


Mmmmouais... Disons qu'une classe est un modèle de construction pour un
objet.


En Python, les objets class ont deux fonctions essentielles :
1. servir d'"usine" à objets
2. fournir les méthodes et autres attributs partagés aux instances

En fait, bien qu'il y ait un truc appelé "classe", le modèle objet de
Python est plus proche des langages à prototypes (javascript, Io,
self...) que des langages à classes.