117

I am looking for something similar to 'clear' in Matlab: A command/function which removes all variables from the workspace, releasing them from system memory. Is there such a thing in Python?

EDIT: I want to write a script which at some point clears all the variables.

braX
  • 11,506
  • 5
  • 20
  • 33
snakile
  • 52,936
  • 62
  • 169
  • 241
  • 3
    It'll be helpful if you changed your title to something like "How do I clear all variables in the middle of a Python script?" for future searches on the topic, because "How to restart the command window in Python?" has nothing to do with what you're actually asking. – Sam Dolan Aug 22 '10 at 23:28
  • Can you provide any possible context in which this makes sense? – S.Lott Aug 23 '10 at 00:47
  • 2
    Sounds like another case of trying to move coding habits from their native environment to one where they don't make any sense. – Glenn Maynard Aug 23 '10 at 01:15
  • 1
    If you're just concerned about some massive objects (images or other huge arrays), you could `del` them when you're done. If you're simply worried about the namespace being cluttered, you should probably reconsider your design using so many names. For example, for a series of image transforms, keeping every interim step is likely unnecessary. – Nick T Aug 23 '10 at 02:51
  • "a script which at some point clears all the variables." Sounds like two scripts. Or -- even more simply -- two functions each with distinct namespaces. Why isn't this just two functions? – S.Lott Aug 23 '10 at 14:10
  • 4
    @S.Lott: exploratory scientific analysis in a console. It's common to end up with many un-wanted variables (after trying things, and then deciding that's not a relevant pathway). But in this case, [John La Rooy's answer](http://stackoverflow.com/a/3543840/210945) is the most appropriate. – naught101 Mar 27 '17 at 05:19
  • @S.Lott As a scientist, I often have to produce plots or run the same analysis on several different files. Do I want to manually reset the kernel each time, and restart my script chaging the filename to load? Nope. Do I want to duplictae my script, making one for each different file I want to use? Nope. Do I want to put all in a big for-loop and loop over a list of filenames? Obviously. And since Python it's extremely fragile, it is great practice to clear all variables between runs to be sure you don't "contaminate" them. The fact that it's not possible is quite mind boggling – F. Remonato Dec 07 '20 at 16:06

11 Answers11

82

The following sequence of commands does remove every name from the current module:

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

I doubt you actually DO want to do this, because "every name" includes all built-ins, so there's not much you can do after such a total wipe-out. Remember, in Python there is really no such thing as a "variable" -- there are objects, of many kinds (including modules, functions, class, numbers, strings, ...), and there are names, bound to objects; what the sequence does is remove every name from a module (the corresponding objects go away if and only if every reference to them has just been removed).

Maybe you want to be more selective, but it's hard to guess exactly what you mean unless you want to be more specific. But, just to give an example:

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

This sequence leaves alone names that are private or magical, including the __builtins__ special name which houses all built-in names. So, built-ins still work -- for example:

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

As you see, name n (the control variable in that for) also happens to stick around (as it's re-bound in the for clause every time through), so it might be better to name that control variable _, for example, to clearly show "it's special" (plus, in the interactive interpreter, name _ is re-bound anyway after every complete expression entered at the prompt, to the value of that expression, so it won't stick around for long;-).

Anyway, once you have determined exactly what it is you want to do, it's not hard to define a function for the purpose and put it in your start-up file (if you want it only in interactive sessions) or site-customize file (if you want it in every script).

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • 3
    Well you could always keep a copy of the original dictionary at startup and then remove names that have been added ;) However I think this is a clear abuse of the dynamic system, and I can't think of a non pointless situation to do this in. – monoceres Aug 22 '10 at 23:26
  • 5
    Haha, this is brilliant... It's surprising how much functionality you lose by doing this, and yet how much functionality you can get back by doing stuff like `int = (2).__class__`, `str = ''.__class__`, `True = (1 == 1)` etc... – Chinmay Kanchi Aug 22 '10 at 23:31
  • @monoceres, how would you name that copy and where would you hide it so it doesn't get wiped away too?-) – Alex Martelli Aug 22 '10 at 23:35
  • Well, since globals() and locals() are fixed when you start the interpreter, you _could_ delete everything except `__builtins__`, '__name__', `__doc__`, `__package__` and your `reset()` function. – Chinmay Kanchi Aug 22 '10 at 23:39
  • @Chinmay, good point, basically the same kind of tricks a hacker would use to escape the attempted sandbox of an `exec` with an empty dict w/o built-ins (you can get at all types via `object.__subclasses__()`, though binding them to their "right" names is marginally trickier;-). – Alex Martelli Aug 22 '10 at 23:40
  • 3
    The more I use Python, the more I love it. Not only is it a great language, you can also spend hours simply fiddling with it and making it do things you really shouldn't ;-) – Chinmay Kanchi Aug 22 '10 at 23:51
  • @Alex: Though importing modules is tougher than just getting to the types. `__import__` is blown away along with `__builtins__`, as are `open()`, `eval()`, `execfile()` and `exec()`. So reimporting, say, `__builtin__` to get everything back is, as far as I can see, not possible. – Chinmay Kanchi Aug 22 '10 at 23:55
  • 1
    Maybe I got it in the wrong way, but I faced one problem: when you use `for n in dir(): ... if n[0]!='_': delattr(this, n)` at some moment `n=this` and you delete it in the loop! So at the next iteration you get Error trying `delattr(this,n)` because you just deleted it! :) So it doesn't work correctly – Mikhail_Sam Oct 27 '17 at 11:40
  • this answer seems to intentionally ignore the obvious intention of the question, i.e. how to write a script that does the equivalent of restarting the interpreter to get rid of variables previously defined – sesquipedalias Jun 17 '20 at 19:08
  • Please put a warning there, for careless people like me who may quickly use this code: `sys.modules[__name__].__dict__.clear()` without reading the entire post!! – NIM4 Aug 14 '20 at 22:32
  • It all still works, what am I missing here? Does Visual Studio just stop you doing this? from sys import modules modules[ _ _ name _ _ ].__dict__.clear() print(str(abs(len("abc" + "def"))) + "\n") class test: def tri(n : int): t = 0 for n2 in range(n): t += n2 print(t) test.tri(3) – alan2here Apr 06 '21 at 18:14
73

No, you are best off restarting the interpreter

IPython is an excellent replacement for the bundled interpreter and has the %reset command which usually works

Leponzo
  • 624
  • 1
  • 8
  • 20
John La Rooy
  • 295,403
  • 53
  • 369
  • 502
  • 3
    By 'No' you mean I shouldn't do it or that it's impossible? If you say I shouldn't do it could you explain why? – snakile Aug 22 '10 at 23:10
  • 6
    +1: It takes less than a quarter of a second for me to `ctrl-d` then `pyt`->`tab` to get back into the interpreter. No reason to do anything fancy here. – Sam Dolan Aug 22 '10 at 23:13
  • 3
    %reset works for most variables, for some it doesn't. For me, only restarting the interpreter guarantees cleaning everything. – artemis_clyde Nov 29 '16 at 23:39
  • 4
    Use `%reset -f` to be non-interactive. https://stackoverflow.com/questions/38798181/ipython-is-there-a-way-to-answer-y-to-or-ignore-all-y-n-prompts – Joachim Wagner May 14 '18 at 14:58
  • Sometimes you dont want to reset the functions previously defined. In such a case it is not a good solution... – Gideon Kogan Nov 15 '22 at 09:49
31

If you write a function then once you leave it all names inside disappear.

The concept is called namespace and it's so good, it made it into the Zen of Python:

Namespaces are one honking great idea -- let's do more of those!

The namespace of IPython can likewise be reset with the magic command %reset -f. (The -f means "force"; in other words, "don't ask me if I really want to delete all the variables, just do it.")

Post169
  • 668
  • 8
  • 26
Jochen Ritzel
  • 104,512
  • 31
  • 200
  • 194
  • 1
    I'll add the obvious: if you put everything inside a main function (including imports) you get in practice a workplace that you can reset just by exiting that function. I believe that's indeed what the question was intended for. – David Sep 18 '18 at 09:33
14
from IPython import get_ipython;   
get_ipython().magic('reset -sf')
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Anurag Gupta
  • 485
  • 5
  • 5
  • 4
    Please have a look at [answer] – Adonis Apr 04 '18 at 08:36
  • 3
    or simply `%reset -sf` – Krishna Nov 29 '18 at 17:15
  • 2
    actually, %reset -sf command does not work and throws error, when you run your python script with anaconda prompt (even though when you have used try- except; it's not working). You may try the same and you will see. But, the use of ipython library will solve this problem, in every possible case. – Anurag Gupta Feb 15 '19 at 10:33
7

This is a modified version of Alex's answer. We can save the state of a module's namespace and restore it by using the following 2 methods...

__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

You can also add a line "clear = restoreContext" before calling saveContext() and clear() will work like matlab's clear.

Jug
  • 540
  • 3
  • 7
  • 2
    Great answer! I believe for Python 3 you'll want to tweak restoreContext with `names = list(sys.modules[__name__].__dict__.keys())`, otherwise Python will complain that you've changed the dictionary size while iterating through it's `dict_keys` object. – Sam Bader Oct 02 '16 at 04:08
  • 1
    Also, for those who want to `import` this answer (ie I have this saved and I import this from a Jupyter notebook to clear the namespace between different problems in a homework assignment), I think you'll want to use `"__main__"` instead of `__name__`. – Sam Bader Oct 02 '16 at 04:10
  • Good answer. It suited perfectly my use case where I am calling Python scripts from R via the `source_python` function from the `reticulate` package and needed to make sure that all Python scripts are executed in a default environment to avoid variables and function definitions leaking from one Python script into another one. – Georg Schnabel Jun 22 '22 at 08:48
4

In Spyder one can configure the IPython console for each Python file to clear all variables before each execution in the Menu Run -> Configuration -> General settings -> Remove all variables before execution.

tardis
  • 1,280
  • 3
  • 23
  • 48
3

Note: you likely don't actually want this.

The globals() function returns a dictionary, where keys are names of objects you can name (and values, by the way, are ids of these objects).

The exec() function takes a string and executes it as if you just type it in a python console. So, the code is

for i in list(globals().keys()):
    if not i.startswith('_'):
        exec('del ' + i)

This will remove all the objects with names not starting with underscores, including functions, classes, imported libraries, etc.

Note: you need to use list() in python 3.x to force a copy of the keys. This is because you cannot add/remove elements in a dictionary while iterating through it.

Kolay.Ne
  • 1,345
  • 1
  • 8
  • 23
  • 1
    While this code snippet may solve the question, [including an explanation](https://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) helps to improve the quality of your response. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Stefan Crain Apr 01 '19 at 19:51
  • Thank you. Is it now better? – Kolay.Ne Apr 02 '19 at 04:16
0

In the idle IDE there is Shell/Restart Shell. Cntrl-F6 will do it.

0

Isn't the easiest way to create a class contining all the needed variables? Then you have one object with all curretn variables, and if you need you can overwrite this variable?

Ivan
  • 1,352
  • 2
  • 13
  • 31
0

A very easy way to delete a variable is by using the del function.

For example

a = 30
print(a) #this would print "30"

del(a) #this deletes the variable
print(a) #now, if you try to print 'a', you will get
         #an error saying 'a' is not defined

0

This worked:

for v in dir():
    exec('del '+ v)
    del v
David Weisser
  • 117
  • 1
  • 10