Python et modules
Bonjour,
Dans l'exemple ci-dessous (sur la base de doc_modules), je me suis créé un petit exemple pour appeler mon propre module. Jusqu'à présent j'ai fait l'impasse sur ce problème, mais je suis obligé d'importer dans chaque fichier les modules Python (numpy et math ici - peut-être une histoire de tables de symboles locaux, je n'ai pas encore bien compris), alors que j'aimerais le faire une bonne fois pour toute dans le fichier principal: où puis-je trouver comment procéder?
Merci
Paul
Fichier principal:
Fichier "module_Fibo.py"
Dans l'exemple ci-dessous (sur la base de doc_modules), je me suis créé un petit exemple pour appeler mon propre module. Jusqu'à présent j'ai fait l'impasse sur ce problème, mais je suis obligé d'importer dans chaque fichier les modules Python (numpy et math ici - peut-être une histoire de tables de symboles locaux, je n'ai pas encore bien compris), alors que j'aimerais le faire une bonne fois pour toute dans le fichier principal: où puis-je trouver comment procéder?
Merci
Paul
Fichier principal:
import module_Fibo import numpy as np from math import sqrt n = 10 A = np.zeros(n, dtype=np.int32) i = np.arange(n) A = module_Fibo.Fibo(i)
Fichier "module_Fibo.py"
from math import sqrt import numpy as np def Fibo(n): phi = (0.5*(1 + sqrt(5)))**n phi_p = (0.5*(1 - sqrt(5)))**n return np.int32((phi - phi_p)/sqrt(5))
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Maintenant, si tu tiens vraiment à faire cette factorisation, tu peux créer un module my_common_imports.py : et faire : dans tes différents modules.
Si tu es CERTAIN que tes fichiers "secondaires" ne seront JAMAIS utilisés seuls, tu peux effectivement te passer de faire les importations dans ces fichiers. Tu fais une importation au début de ton fichier principal, puis, dans ce fichier principal, tu importes les autres fichiers.
Dans tous les autres cas, ça ne coûte absolument rien de mettre les importations dans tes fichiers secondaires. Cela prend certes quelques lignes et quelques octets de données... mais ces importations seront simplement ignorées si les modules en question sont déjà importés, donc ne feront perdre aucun temps à l'exécution.
Il faut cependant faire attention à ne pas mélanger les noms d'un fichier à l'autre...
Si tu le fais dans l'autre sens, ça devrait marcher.
Cela semble correspondre un peu plus à ce que tu voudrais faire.
« Tout devient local » : oui au niveau espace de nommage, non au niveau occupation mémoire.
Au sein d'un interpréteur Python donné, un module donné est chargé au plus une fois. Les imports suivants d'un module déjà chargé faits au cours de la même exécution du programme sont immédiats et n'accroissent pas l'occupation mémoire car ils ne font rien du tout, sinon ajouter un « pointeur » dans le module courant vers le module déjà chargé.
Ceci est implémenté à l'aide d'un dictionnaire, sys.modules : Le 'base64' tout seul ci-dessus « pointe » vers l'objet <module 'base64' from '/usr/lib/python3.8/base64.py'>. Comme le montre la dernière commande, sys.modules["base64"] pointe vers exactement le même objet, et si 'base64' est importé par un autre module au cours de la même exécution, un « pointeur » top-level pointera aussi, comme le 'base64' tout seul ci-dessus, vers le même objet.
Bon, en fait, il n'y a pas explicitement de pointeurs en Python, c'est juste que toute variable, tout attribut d'un objet est un pointeur, dans les faits. Cela économise beaucoup la mémoire mais peut jouer des tours lorsqu'on modifie un objet mutable référencé (pointé) depuis divers endroits. On a eu une discussion à ce sujet initiée par GaBuZoMeu il y a quatre mois sur ce forum.
je l'ai lu, mais je ne comprends toujours pas; ce paragraphe décrit comment déclarer tous les fichiers .py qui constituent mon module dans un fichier__init__.py; je n'imagine pas qu'il me faille déclarer un numpy.py ou math.py dans ce __init__.py ...
et
si ça te casse les pieds de préfixer ces appels par module.Fibo tu n'as qu'à déclarer au début de ton script une variable np :
ton script principal deviendrait :
Quel est l'intérêt de faire : au lieu de ? À part si l'on souhaite vraiment ajouter un niveau d'indirection, je ne vois pas trop. :-S
Dans ton troisième message, tu dis bien que les modules ne sont chargés qu'une fois, pour autant il faut les déclarer dans chaque fichier: j'espérais trouver un moyen de n'appeler les modules que dans le fichier principal.
J'entrevois la réponse finale qui va dire que c'est lié à des choix techniques (table de symboles, espace de nommage, etc) des développeurs Python, et qu'il faut vivre avec, non ?
À mon avis, point de raisons techniques à cela, mais plutôt de propreté du langage — comme expliqué dans mon premier message.
Voici ce que tu souhaites apparemment faire. Attention, ça pique les yeux. Je ne le conseille pas du tout.
main.py : module_Fibo.py : Test :
Ta première solution reste la plus simple. Je ne comprends pas que cela ne soit nativement pas possible dans Python, mais je vais arrêter de me poser la question.
Merci pour la solution
Paul
Parce que tu veux faire du ski, sans avoir à mettre des skis. 8-)
Solution: soit tu as des skis en permanence, soit tu dévales la pente à pied. Dans les deux cas, c'est absurde. Voilà pourquoi cela n'est envisagé par personne.
Prends tes imports comme une porte d'entrée obligatoire dans ton espace merveilleux où tout fonctionne.