40 votes

Comment dé-importer un module Python ?

Je suis en train de coder une application qui doit récupérer les métadonnées (auteur, version..etc) de plusieurs modules (fichiers .py) et les afficher. L'utilisateur sélectionne un script et le script est exécuté. (De nouveaux scripts peuvent être ajoutés et les anciens peuvent être retirés du dossier cible, tout comme un système de plugins).

D'abord j'importe un script et je retire les métadonnées, puis je passe au suivant. Mais je veux dé-importer tous les autres modules sauf celui que l'utilisateur a sélectionné.

Comment puis-je mettre cela en œuvre ?

J'ai essayé ceux-là

1. del module
2. del sys.modules['module']

Ce dernier n'a pas fonctionné. J'ai essayé #python et j'ai obtenu la réponse qu'il n'était pas bon de dé-importer des modules, mais je veux connaître un moyen propre de mettre en œuvre cela. Toute idée/suggestion m'aiderait.

8 votes

Il y a est pas de moyen propre de désimporter les modules. Tout ce que vous allez faire passe par des hacks.

0 votes

Obtenez des métadonnées en analysant le code à l'aide de la fonction ast au lieu de les importer, comme le font les outils tels que Epydoc , PyDoctor et Sphinx faire.

20voto

gabtub Points 1102

Je pense ce poste devrait vous aider

modifier : Afin de garantir la disponibilité de cette information (au cas où le lien disparaîtrait ou quelque chose de similaire), je vais inclure le message original de la page d'accueil. liste de diffusion des tuteurs ici :


Le 14/08/06, Dick Moores a écrit :

En fait, ma question est la suivante : après avoir utilisé IDLE pour importer des modules et initialiser des variables. modules et l'initialisation des variables, comment revenir à son initial sans le fermer et le rouvrir.

Donc, par exemple, après avoir fait

>>> import math, psyco
>>> a = 4**23

Comment puis-je les effacer sans fermer IDLE ? (J'avais l'habitude de savoir comment, mais j'ai oublié).

Salut Dick,

Habituellement, cela implique la suppression du "registre des modules" et la suppression des références à celui-ci dans le code. références à celui-ci dans le code. Si vous avez un vraiment module bien utilisé (comme un module avec des paramètres de configuration importés dans chaque module), alors vous aurez une étape supplémentaire pour le supprimer de chaque module. De plus, si vous avez utilisé "from psyco import ...", alors vous ne pourrez pas libérer le module et module et de la référence au module (est-ce qu'il provient de ce module ou est-il un troisième module ? voir "if paranoid : code ci-dessous).

La fonction ci-dessous supprime un module par son nom de l'interpréteur Python, la fonction paramètre "paranoïaque" est une liste de noms de variables à supprimer de tous les autres modules (censés être supprimés avec le module). Soyez TRES prudent avec le paramètre paramètre paranoid ; cela pourrait causer des problèmes à votre interpréteur si vos fonctions et classes portent le même nom dans différents modules. Un cas courant Une occurrence courante de ceci est "error" pour les exceptions. Beaucoup de bibliothèques ont une beaucoup de bibliothèques ont une exception "attrape-tout" appelée "error" dans le module. Si vous avez également nommé votre exception "error" et que vous décidez de l'inclure dans la liste paranoïaque... beaucoup d'autres objets d'exception.

def delete_module(modname, paranoid=None):
    from sys import modules
    try:
        thismod = modules[modname]
    except KeyError:
        raise ValueError(modname)
    these_symbols = dir(thismod)
    if paranoid:
        try:
            paranoid[:]  # sequence support
        except:
            raise ValueError('must supply a finite list for paranoid')
        else:
            these_symbols = paranoid[:]
    del modules[modname]
    for mod in modules.values():
        try:
            delattr(mod, modname)
        except AttributeError:
            pass
        if paranoid:
            for symbol in these_symbols:
                if symbol[:2] == '__':  # ignore special symbols
                    continue
                try:
                    delattr(mod, symbol)
                except AttributeError:
                    pass

Ensuite, vous devriez pouvoir l'utiliser comme ça :

delete_module('psyco')

ou

delete_module('psyco', ['Psycho', 'KillerError'])
# only delete these symbols from every other module
# (for "from psyco import Psycho, KillerError" statements)

-Arcege

3 votes

Pouvez-vous en résumer le contenu ici si ce lien venait à disparaître ?

0 votes

Merci pour le lien... mais y a-t-il un autre moyen d'obtenir les métadonnées que l'importation ?

7voto

Ehsan Foroughi Points 538

Suggestion : Importez vos modules de manière dynamique en utilisant __import__

Par exemple

module_list = ['os', 'decimal', 'random']
for module in module_list:
    x = __import__(module)
    print 'name: %s - module_obj: %s' % (x.__name__, x)

Produira :

name: os - module_obj: <module 'os' from '/usr/lib64/python2.4/os.pyc'>
name: decimal - module_obj: <module 'decimal' from '/usr/lib64/python2.4/decimal.pyc'>
name: random - module_obj: <module 'random' from '/usr/lib64/python2.4/random.pyc'>

Cependant, cela ne le supprimera pas vraiment du registre des modules. La prochaine fois qu'il sera importé, il ne relira pas le fichier de paquetage/module et ne l'exécutera pas. Pour ce faire, vous pouvez simplement modifier l'extrait de code ci-dessus comme suit :

import sys
module_list = ['os', 'decimal', 'random', 'test1']
for module_name in module_list:
    x = __import__(module_name)
    print 'name: %s - module_obj: %s' % (x.__name__, x)
    del x
    sys.modules.pop(module_name)

6voto

Grunthos the Poet Points 101

J'ai récemment trouvé ce post https://www.geeksforgeeks.org/reloading-modules-python/ et donc, pour Python 3.4 ou plus, utilisez

import importlib
importlib.reload(module)

2voto

LittleDong Points 1

Je sais que ce message n'est plus d'actualité mais je viens de rencontrer ce problème et je me suis battu contre lui ces derniers jours. Maintenant, je suis arrivé à une conclusion qui peut parfaitement résoudre ce problème. Veuillez voir l'exemple de code ci-dessous :

try:
    theMod = sys.modules['ModNeedToBeDel']   
except:
    theMod = None
if theMod:
    del sys.modules['ModNeedToBeDel']

#The extra try/except below is because I implemented the block in a module of a sub-package; this ModNeedToBeDel in my case was imported either by the toppest level Main code, or by the other sub-package modules. That's why I need two different try/except.

try:
    theMod = sys.modules['UpperFolder.ModNeedToBeDel']   
except:
    theMod = None
if theMod:
    del sys.modules['UpperFolder.ModNeedToBeDel']
import ModNeedToBeDel   # or UpperFolder.ModNeedToBeDel here

Notez que del sys.modules[theMod] ne fonctionnera pas, parce qu'il supprime juste la référence, au lieu de la véritable ModNeedToBeDel .

J'espère que cela pourra aider quelqu'un afin qu'il n'ait pas à se débattre avec ce problème pendant plusieurs jours !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X