OVH Cloud OVH Cloud

reload et unload ?

10 réponses
Avatar
Olivier Ravard
Bonjour à tous,

Tout le monde a déjà utilisé la fonction reload pour recharger un module.
Mais existe-t-il l'équivalent pour "oublier" un module ? (par exemple
unload).

Merci de vos réponses.

O.R.

10 réponses

Avatar
Olivier
Bonjour à tous,

Tout le monde a déjà utilisé la fonction reload pour recharger un module.
Mais existe-t-il l'équivalent pour "oublier" un module ? (par exemple
unload).



del ?

import string
string.zfill
<function zfill at 0x008D3BF0>



del string
string.zfill
Traceback (most recent call last):



File "<stdin>", line 1, in ?
NameError: name 'string' is not defined


Olivier



Avatar
Laurent Pointal
Olivier wrote:

Bonjour à tous,

Tout le monde a déjà utilisé la fonction reload pour recharger un module.
Mais existe-t-il l'équivalent pour "oublier" un module ? (par exemple
unload).




del ?


del supprime un nom dans un espace de noms.

A ma connaissance, il n'y a pas de système de déchargement de module en
Python (il faudrais trouver tous les noms qui référencent qq chose dans
le module en question... et les supprimer - quel impact sur le
fonctionnement).

Mais, même avec reload, je ne suis pas sûr que le code précédent soit
oublié (on relit dans le dictionnaire des modules... mais les scripts
déjà compilés qui référencent des éléments de l'ancien code conservent
leurs anciennes références valides).

A+

Laurent.


Avatar
tiissa
Olivier Ravard wrote:
Mais existe-t-il l'équivalent pour "oublier" un module ? (par exemple
unload).


Comme cela a déjà été dit, il semble ne pas exister de commande pour
oublier un module.
'del' va supprimer le nom du module des variables globales. On peut
imaginer que, comme tout objet, il risque la destruction totale si plus
aucune référence n'existe sur lui.
Mais c'est au ramasse-miettes de voir.


Personnellement, je n'ai jamais eu envie d'oublier un module. Que
voulez-vous faire qui vous procure ce besoin ?

Avatar
Christophe Cavalaria
tiissa wrote:

Olivier Ravard wrote:
Mais existe-t-il l'équivalent pour "oublier" un module ? (par exemple
unload).


Comme cela a déjà été dit, il semble ne pas exister de commande pour
oublier un module.
'del' va supprimer le nom du module des variables globales. On peut
imaginer que, comme tout objet, il risque la destruction totale si plus
aucune référence n'existe sur lui.
Mais c'est au ramasse-miettes de voir.


Personnellement, je n'ai jamais eu envie d'oublier un module. Que
voulez-vous faire qui vous procure ce besoin ?


del va retirer la reference au module des variables globales du module
courant ! Si il y a eu un import dans un troisieme module alors il restera
toujours une reference vivante.

Et de toute façon, Python garde tous les modules chargés dans un dictionaire
donc il n'est pas possible de perdre la dernière reference pour supprimer
celui-ci de la mémoire.


Avatar
Olivier Ravard
"tiissa" a écrit dans le message de news:
4331bab5$0$29681$
Olivier Ravard wrote:
Mais existe-t-il l'équivalent pour "oublier" un module ? (par exemple
unload).


Comme cela a déjà été dit, il semble ne pas exister de commande pour
oublier un module.
'del' va supprimer le nom du module des variables globales. On peut
imaginer que, comme tout objet, il risque la destruction totale si plus
aucune référence n'existe sur lui.
Mais c'est au ramasse-miettes de voir.


Personnellement, je n'ai jamais eu envie d'oublier un module. Que
voulez-vous faire qui vous procure ce besoin ?


Mon appli compile des modules en C qui sont chargés de manière dynamique
par l'interprêteur (extension .pyd). Lorsque l'utilisateur recompile un
module déjà chargé il a besoin
de remplacer le fichier .pyd associé mais l'ancien étant utilisé, il est
impossible de
l'effacer (sous windows mais pas Linux) ...
Mon problème est donc de remplacer un fichier .pyd déjà chargé par
l'interprêteur
par une nouvelle version et recharger le module, tout ceci sans redémarrer
l'interprêteur.

Mon explication est-elle suffisamment claire ?

O.R.


Avatar
Pierre Quentel


Mon appli compile des modules en C qui sont chargés de manière dynamique
par l'interprêteur (extension .pyd). Lorsque l'utilisateur recompile un
module déjà chargé il a besoin
de remplacer le fichier .pyd associé mais l'ancien étant utilisé, il est
impossible de
l'effacer (sous windows mais pas Linux) ...
Mon problème est donc de remplacer un fichier .pyd déjà chargé par
l'interprêteur
par une nouvelle version et recharger le module, tout ceci sans redémarrer
l'interprêteur.

Mon explication est-elle suffisamment claire ?

O.R.


L'interpréteur garde une référence à tous les modules déjà importés dans

le dictionnaire sys.modules. Ses clés sont les noms de modules et les
valeurs, les objets modules correspondants

Quand l'interpréteur rencontre une instruction "import un_module" il
regarde d'abord si sys.modules a une clé "un_module" et si oui, il
récupère l'objet module, sans essayer de le recharger

Si tu sais que le module a changé il faut faire

del sys.modules["un_module"]

comme ça au prochain import l'interpréteur rechargera la nouvelle version

Est-ce que cela répond à ta question ?

A+
Pierre

Avatar
Do Re Mi chel La Si Do
Bonsoir !


Le del sys.modules["un_module"] ne suffit pas toujours.


Exemple :

Soit le module mod1.py :
def aaa():
print "aaa"
def bbb():
print "bbb"


Et le script suivant :

import time,sys

import mod1
a=mod1.aaa
b=mod1.bbb
a()
b()

time.sleep(30) #voir note plus bas
del sys.modules["mod1"]
print '-'*55

import mod1
a=mod1.aaa
a()
b()



#note : durant l'attente, on modifie le module mod1.py, qui devient comme
suit :
def aaa():
print "aaa"*3



A l'exécution du script, on voit bien que :
- le def aaa() a bien été remplacé par la nouvelle version,
- def bbb() n'a pas été supprimé par le del

Cela est dû au fait que mod1.bbb est référencé par b ; ni le del, ni le
garbage collector ne supprimeront cette fonction.


Conclusion : le del sys.modules["un_module"] est a manier avec
circonspection.




@-salutations
--
Michel Claveau
Avatar
Olivier Ravard
"Pierre Quentel" a écrit dans le message de
news: 43345dc1$0$5393$
Si tu sais que le module a changé il faut faire

del sys.modules["un_module"]

comme ça au prochain import l'interpréteur rechargera la nouvelle version

Est-ce que cela répond à ta question ?

Non. Car mon problème de base est de savoir comment je peux remplacer un

fichier
".pyd" sous windows equivalent aux ".so" sous linux.
Une fois qu'un module a été chargé, on ne peut pas effacer le fichier...

Avatar
Christophe
"Pierre Quentel" a écrit dans le message de
news: 43345dc1$0$5393$

Si tu sais que le module a changé il faut faire

del sys.modules["un_module"]

comme ça au prochain import l'interpréteur rechargera la nouvelle version

Est-ce que cela répond à ta question ?



Non. Car mon problème de base est de savoir comment je peux remplacer un
fichier
".pyd" sous windows equivalent aux ".so" sous linux.
Une fois qu'un module a été chargé, on ne peut pas effacer le fichier...




C'est probablement impossible tel quel. Mais une possibilité serait de :
- crééer un module d'extension qui va se plugger dans le code de import
de module.
- ce module va intercepter toute demande d'importe qui aboutit à un
fichier .pyd ( qui est un fichier .dll renommé )
- ce module va ouvrir le fichier, le charger en mémoire puis fermer le
fichier
- enfin, ce module va activer le fichier .dll à partir de son contenu en
mémoire.

Ces 4 étapes sont par ordre de difficultée :) La dernière étant la plus
difficile car l'appel système windows chargé d'importer une dll n'a pas
son code source dispo et il faut donc reproduire son comportement soit
même ce qui n'est pas très fiable. L'auteur de py2exe à fait cela dans
la dernière version si je ne m'abuse ( possibilité de faire un .exe qui
ne crée aucun fichiers au lancement, même s'il y a des .pyd dans l'archive )

Autre possibilité, faire passer les gens sous un vrai OS qui ne met pas
des restrictions abusives sur les fichiers .dll et .exe en cours
d'utilisation.


Avatar
Olivier Ravard
"Christophe" a écrit dans le message de news:
4337c519$0$11751$

C'est probablement impossible tel quel. Mais une possibilité serait de :
- crééer un module d'extension qui va se plugger dans le code de import de
module.
- ce module va intercepter toute demande d'importe qui aboutit à un
fichier .pyd ( qui est un fichier .dll renommé )
- ce module va ouvrir le fichier, le charger en mémoire puis fermer le
fichier
- enfin, ce module va activer le fichier .dll à partir de son contenu en
mémoire.

Ces 4 étapes sont par ordre de difficultée :) La dernière étant la plus
difficile car l'appel système windows chargé d'importer une dll n'a pas
son code source dispo et il faut donc reproduire son comportement soit
même ce qui n'est pas très fiable. L'auteur de py2exe à fait cela dans la
dernière version si je ne m'abuse ( possibilité de faire un .exe qui ne
crée aucun fichiers au lancement, même s'il y a des .pyd dans l'archive )



Merci pour ces idées. Je pense que je vais suivre cette voie.

Autre possibilité, faire passer les gens sous un vrai OS qui ne met pas
des restrictions abusives sur les fichiers .dll et .exe en cours
d'utilisation.


Tout à fait d'accord. Je me tue à l'expliquer à mes clients...
D'autant plus que sans parler ce cet aspect, ce qui m'énerve sous W.. est la
gestion de la mémoire et des threads qui laisse vraiment à désirer.

O.R.