104 votes

Comment effacer toutes les variables au milieu d'un script Python ?

Je cherche quelque chose de similaire à "clear" dans Matlab : Une commande/fonction qui supprime toutes les variables de l'espace de travail, les libérant de la mémoire système. Existe-t-il une telle chose en Python ?

EDIT : Je veux écrire un script qui à un moment donné efface toutes les variables.

2 votes

Il serait utile que vous changiez votre titre en quelque chose comme "Comment puis-je effacer toutes les variables au milieu d'un script Python ?" pour les futures recherches sur le sujet, parce que "Comment redémarrer la fenêtre de commande en Python ?" n'a rien à voir avec ce que vous demandez réellement.

0 votes

Pouvez-vous fournir un contexte possible dans lequel cela a un sens ?

2 votes

Cela ressemble à un autre cas où l'on essaie de déplacer les habitudes de codage de leur environnement d'origine vers un environnement où elles n'ont aucun sens.

79voto

Alex Martelli Points 330805

La séquence de commandes suivante permet de supprimer chaque du module actuel :

>>> import sys
>>> sys.modules[__name__].__dict__.clear()

Je doute que vous souhaitiez réellement faire cela, car "chaque nom" inclut tous les build-ins, donc il n'y a pas grand chose que vous puissiez faire après un tel effacement total. Rappelez-vous qu'en Python, il n'existe pas vraiment de "variable" -- il y a des "variables". objets de nombreux types (y compris des modules, des fonctions, des classes, des nombres, des chaînes de caractères, etc. noms Cette séquence permet de supprimer tous les noms d'un module (les objets correspondants disparaissent si et seulement si toutes les références à ces objets ont été supprimées).

Vous voulez peut-être être plus sélectif, mais il est difficile de deviner ce que vous voulez dire exactement, à moins que vous ne vouliez être plus précis. Mais, juste pour donner un exemple :

>>> import sys
>>> this = sys.modules[__name__]
>>> for n in dir():
...   if n[0]!='_': delattr(this, n)
... 
>>>

Cette séquence laisse seuls les noms qui sont privés ou magiques, y compris le __builtins__ un nom spécial qui abrite tous les noms des modules intégrés. Ainsi, les built-ins fonctionnent toujours -- par exemple :

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'n']
>>> 

Comme vous le voyez, le nom n (la variable de contrôle dans cette for ) se trouve également à rester dans les parages (puisqu'elle est reliée à nouveau dans le fichier for à chaque passage), il serait donc préférable de nommer cette variable de contrôle _ par exemple, pour montrer clairement "c'est spécial" (de plus, dans l'interpréteur interactif, le nom _ est de toute façon lié de nouveau après chaque expression complète entrée à l'invite, à la valeur de cette expression, de sorte qu'il ne restera pas longtemps en place;-).

Quoi qu'il en soit, une fois que vous avez déterminé exactement ce qu'il est que vous voulez faire, il n'est pas difficile de définir une fonction à cet effet et de la mettre dans votre fichier de démarrage (si vous ne le voulez que dans les sessions interactives) ou dans le fichier de personnalisation du site (si vous le voulez dans chaque script).

3 votes

Eh bien, vous pourriez toujours conserver une copie du dictionnaire original au démarrage et ensuite supprimer les noms qui ont été ajoutés ;) Cependant, je pense qu'il s'agit là d'un abus manifeste du système dynamique, et je n'arrive pas à imaginer une situation où cela ne serait pas inutile.

5 votes

Haha, c'est génial... C'est surprenant de voir combien de fonctionnalités on perd en faisant ça, et pourtant combien de fonctionnalités on peut récupérer en faisant des trucs comme int = (2).__class__ , str = ''.__class__ , True = (1 == 1) etc...

0 votes

@monoceres, comment nommerais-tu cette copie et où la cacherais-tu pour qu'elle ne soit pas effacée aussi ?-)

71voto

gnibbler Points 103484

Non, il est préférable de redémarrer l'interpréteur.

IPython est un excellent substitut à l'interpréteur intégré et possède les caractéristiques suivantes %reset qui fonctionne généralement

1 votes

Par "non", vous voulez dire que je ne devrais pas le faire ou que c'est impossible ? Si vous dites que je ne devrais pas le faire, pouvez-vous expliquer pourquoi ?

6 votes

+1 : Il me faut moins d'un quart de seconde pour ctrl-d puis pyt -> tab pour revenir dans l'interpréteur. Il n'y a pas de raison de faire quelque chose de compliqué ici.

3 votes

%reset fonctionne pour la plupart des variables, mais pas pour certaines. Pour moi, seul le redémarrage de l'interpréteur garantit le nettoyage de tout.

31voto

Jochen Ritzel Points 42916

Si vous écrivez une fonction, tous les noms qu'elle contient disparaissent dès que vous la quittez.

Ce concept est appelé espace de noms et c'est tellement bon que c'est passé dans le Zen du python :

Les espaces de noms sont une idée géniale. -- faisons-en plus !

L'espace de noms d'IPython peut également être réinitialisé avec la commande magique %reset -f . (Le -f signifie "forcer" ; en d'autres termes, "ne me demandez pas si je veux vraiment supprimer toutes les variables, faites-le").

1 votes

J'ajouterai l'évidence : si vous placez tout à l'intérieur d'une fonction principale (y compris les importations), vous obtenez en pratique un lieu de travail que vous pouvez réinitialiser simplement en sortant de cette fonction. Je pense que c'est effectivement le but de la question.

12voto

Anurag Gupta Points 75
from IPython import get_ipython;   
get_ipython().magic('reset -sf')

4 votes

Jetez un coup d'œil à Comment répondre

2 votes

Ou simplement %reset -sf

2 votes

En fait, la commande %reset -sf ne fonctionne pas et lance une erreur, lorsque vous exécutez votre python script avec le prompt anaconda (même si lorsque vous avez utilisé try- except ; cela ne fonctionne pas). Vous pouvez essayer la même chose et vous verrez. Mais, l'utilisation de la bibliothèque ipython résoudra ce problème, dans tous les cas possibles.

6voto

Jug Points 365

Il s'agit d'une version modifiée de la réponse d'Alex. Nous pouvons sauvegarder l'état de l'espace de nom d'un module et le restaurer en utilisant les 2 méthodes suivantes...

__saved_context__ = {}

def saveContext():
    import sys
    __saved_context__.update(sys.modules[__name__].__dict__)

def restoreContext():
    import sys
    names = sys.modules[__name__].__dict__.keys()
    for n in names:
        if n not in __saved_context__:
            del sys.modules[__name__].__dict__[n]

saveContext()

hello = 'hi there'
print hello             # prints "hi there" on stdout

restoreContext()

print hello             # throws an exception

Vous pouvez également ajouter une ligne "clear = restoreContext" avant d'appeler saveContext() et clear() fonctionnera comme clear de matlab.

1 votes

Excellente réponse ! Je pense que pour Python 3, vous devrez modifier restoreContext avec names = list(sys.modules[__name__].__dict__.keys()) sinon Python se plaindra que vous avez modifié la taille du dictionnaire tout en itérant à travers son fichier dict_keys objet.

0 votes

Aussi, pour ceux qui veulent import cette réponse (c'est-à-dire que je l'ai sauvegardée et que je l'importe d'un carnet Jupyter pour effacer l'espace de noms entre les différents problèmes d'un devoir), je pense que vous voudrez utiliser "__main__" au lieu de __name__ .

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