175

I've been searching for the accurate answer to this question for a couple of days now but haven't got anything good. I'm not a complete beginner in programming, but not yet even on the intermediate level.

When I'm in the shell of Python, I type: dir() and I can see all the names of all the objects in the current scope (main block), there are 6 of them:

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']

Then, when I'm declaring a variable, for example x = 10, it automatically adds to that lists of objects under built-in module dir(), and when I type dir() again, it shows now:

['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x']

The same goes for functions, classes and so on.

How do I delete all those new objects without erasing the standard 6 which where available at the beginning?

I've read here about "memory cleaning", "cleaning of the console", which erases all the text from the command prompt window:

>>> import sys
>>> clear = lambda: os.system('cls')
>>> clear()

But all this has nothing to do with what I'm trying to achieve, it doesn't clean out all used objects.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
rombez
  • 2,047
  • 2
  • 16
  • 16
  • 2
    Why do you feel you need to do this, or are you just asking out of curiosity? – PM 2Ring Oct 24 '14 at 10:05
  • I just didn't know that there is a `del` function out there. I'm beginning to learn Python and often have to experiment in the shell, so standard variable names like `x` or `y` are often already in use and restarting the shell takes another 15 sec to do (I have a very, very old laptop now). So I wanted to find a way to clean Python memory quicker. – rombez Oct 24 '14 at 14:52
  • 1
    Ah. FWIW, `del` isn't exactly a function, hence no `(` and `)`. It's a keyword which introduces a del statement. Of course, how it actually deletes an object may involve functions, but that's another story... – PM 2Ring Oct 25 '14 at 05:08
  • When experimenting in the shell names like `x` or `y` should not be in use unless _you_ are using them. Or unless you do something silly like `from _somemodule_ import *`, then you'll get all sorts of garbage cluttering up the place. :) – PM 2Ring Oct 25 '14 at 05:08
  • Possible duplicate of [How do I clear all variables in the middle of a Python script?](http://stackoverflow.com/questions/3543833/how-do-i-clear-all-variables-in-the-middle-of-a-python-script) – smac89 Apr 23 '16 at 21:53
  • @Smac89: I think that the answers to my questions are better ones, because they contain additional information and are much simpler than those provided for the question referenced. Is it still should be considered a duplicate and removed even if answers are better? Thank you. – rombez Apr 25 '16 at 07:59
  • 1
    I googled my way to this question and now I am wondering - why can't i just restart the kernel and re-run the script from the top if I want to delete all variables and functions anyway? – vagabond Apr 06 '17 at 13:13

8 Answers8

231

You can delete individual names with del:

del x

or you can remove them from the globals() object:

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

This is just an example loop; it defensively only deletes names that do not start with an underscore, making a (not unreasoned) assumption that you only used names without an underscore at the start in your interpreter. You could use a hard-coded list of names to keep instead (whitelisting) if you really wanted to be thorough. There is no built-in function to do the clearing for you, other than just exit and restart the interpreter.

Modules you've imported (import os) are going to remain imported because they are referenced by sys.modules; subsequent imports will reuse the already imported module object. You just won't have a reference to them in your current global namespace.

Python doesn’t make any security guarantees about data in memory however. When objects no longer are referenced the interpreter marks the memory as no longer in use but does not take steps to overwrite that memory to prevent access to data. If you need that level of security protection you’ll need to use third-party extensions that manage their own memory with security in mind.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Well, I have to say `startswith('_')` seems quite naive. If someone is smart enough to write `_foo=42` or even `__foo__=42`, how can we delete these? Is there a way to obtain standard module properties' names programmatically? – georg Oct 24 '14 at 09:29
  • 3
    @georg: I've coded the loop defensively. You'll have to hardcode an initial list of names to keep if you want to do better. – Martijn Pieters Oct 24 '14 at 09:29
  • So, no way? My thought was `dir(ModuleType())`, but it only returns `doc` and `name`. – georg Oct 24 '14 at 09:42
  • 1
    @georg: nope; the global namespace of the interpreter varies from release to release as well, and there is not foolproof way (that I know of) to enumerate what was in there when you opened the interpreter *at a later stage*. – Martijn Pieters Oct 24 '14 at 09:46
  • @georg: So if you really need to do this, just make a copy of the globals before you start adding stuff to the interpreter's name space. But why do you (or the OP) need to do this? If I have some large object I want gc'ed I usually just assign its name to something else, or occasionally I `del` it. And if the namespace gets too cluttered I simply kill the interpreter & restart it. – PM 2Ring Oct 24 '14 at 10:01
  • @PM2Ring: Right, there's no practical use for this, I'm asking out of pure curiosity (just like the OP, I guess). – georg Oct 24 '14 at 10:03
  • @georg, that's because you used Python 2, while the OP used Python 3. In CPython you should get everything the OP listed except `__builtins__`, which you can get with an `exec`, i.e. `m = types.ModuleType(''); exec('', vars(m)); dir(m)`. – Eryk Sun Oct 24 '14 at 11:30
  • @eryksun: in Python 2 that still leaves out `__package__` (which is bound to `None`, so not that big a problem). I just don't want to advocate the approach as different Python versions might introduce additional names that are not recoverable through that process; it is just not reliable enough. – Martijn Pieters Oct 24 '14 at 11:35
  • @eryksun: yes, I mean `sys.modules['__main__']` here; the interactive interpreter namespace. – Martijn Pieters Oct 24 '14 at 11:35
  • The second example also removes function and classes –  Jun 12 '20 at 15:46
  • 1
    @nakE functions and classes are just objects like any other. They are not special; use a whitelist or check the object type of you need to preserve classes and functions. – Martijn Pieters Jun 17 '20 at 22:30
  • This doesn't work. Variable data will still show up in the core dump of memory with `gcore $PID` - even with gc.collect(), even after creating junk data to fill up memory, it's still there. – SurpriseDog Jun 20 '21 at 20:07
  • @SurpriseDog that wasn’t the question. There is no security guarantees here, just that the Python interpreter has forgotten about the name. – Martijn Pieters Jun 20 '21 at 20:16
  • @MartijnPieters There has to be a way to overwrite the variables in memory. I thought creating enough junk data would do it, but I don't understand why that's not working. – SurpriseDog Jun 20 '21 at 20:20
  • @SurpriseDog Python memory management isn’t that simple and I would not even begin trying to make Python wipe memory. – Martijn Pieters Jun 20 '21 at 20:22
94

Yes. There is a simple way to remove everything in iPython. In iPython console, just type:

%reset

Then system will ask you to confirm. Press y. If you don't want to see this prompt, simply type:

%reset -f

This should work..

EyesBear
  • 1,376
  • 11
  • 21
  • 2
    Once again, why isn't this one the top answer? – myradio Jun 06 '19 at 07:50
  • 43
    @myradio Because it's irrelevant to everybody not using [IPython](https://en.wikipedia.org/wiki/IPython), and, it neither answers the question; the question asks how to delete global object references, not reset the content of the [IPython](https://en.wikipedia.org/wiki/IPython) [shell](https://en.wikipedia.org/wiki/Shell_(computing)). – Andreas is moving to Codidact Oct 06 '19 at 20:50
  • 2
    This was the magic command I was looking for in Jupyter Notebook to clear variables (to free up CPU/GPU Ram) without restarting kernel! – Gorkem Mar 24 '21 at 23:33
31

You can use python garbage collector:

import gc
gc.collect()
Fardin Abdi
  • 1,284
  • 15
  • 20
  • 10
    Hey @Fardin! thanks! Your answer did the job and saved my day! But before gc.collect() I did del(variable). – Gmosy Gnaq Jul 31 '18 at 13:34
  • 9
    gc.collect() itself will not work. Like Gmosy mentioned above del(variable name) must be used. – Nguai al Nov 07 '20 at 18:11
  • gc.collect() seems to do nothing. All variables are still accessible. – Peter Leopold Dec 25 '21 at 03:45
  • Garbage collection only cleans up objects from memory that are no longer referenced. The question is how to delete the references. Garbage collection will run automatically, it is not normally needed to trigger it manually. – mkrieger1 May 14 '23 at 20:23
12

If you are in an interactive environment like Jupyter or ipython you might be interested in clearing unwanted var's if they are getting heavy.

The magic-commands reset and reset_selective is vailable on interactive python sessions like ipython and Jupyter

1) reset

reset Resets the namespace by removing all names defined by the user, if called without arguments.

in and the out parameters specify whether you want to flush the in/out caches. The directory history is flushed with the dhist parameter.

reset in out

Another interesting one is array that only removes numpy Arrays:

reset array

2) reset_selective

Resets the namespace by removing names defined by the user. Input/Output history are left around in case you need them.

Clean Array Example:

In [1]: import numpy as np
In [2]: littleArray = np.array([1,2,3,4,5])
In [3]: who_ls
Out[3]: ['littleArray', 'np']
In [4]: reset_selective -f littleArray
In [5]: who_ls
Out[5]: ['np']

Source: http://ipython.readthedocs.io/en/stable/interactive/magics.html

user1767754
  • 23,311
  • 18
  • 141
  • 164
12

This should do the trick.

globals().clear()
Aps
  • 214
  • 2
  • 9
  • It would be helpful to add a line stating why this works! – Anurag A S May 01 '21 at 06:36
  • 1
    This is the only suggestion that works in a basic python shell. – Peter Leopold Dec 25 '21 at 03:44
  • 1
    This freed more than 50% of the physical and virtual memory that I have been unable to free by any other means, other than `del globals()[name]`, variable by variable. I am running a script in Spyder. Still figuring out where the remaining 40% is.... – Larry Panozzo Jul 22 '22 at 23:16
  • This is the only answer that worked for me! Is there a way to do this such that we don't have to run the command "import numpy" again? – Nike Dec 06 '22 at 18:59
10

Actually python will reclaim the memory which is not in use anymore.This is called garbage collection which is automatic process in python. But still if you want to do it then you can delete it by del variable_name. You can also do it by assigning the variable to None

a = 10
print a 

del a       
print a      ## throws an error here because it's been deleted already.

The only way to truly reclaim memory from unreferenced Python objects is via the garbage collector. The del keyword simply unbinds a name from an object, but the object still needs to be garbage collected. You can force garbage collector to run using the gc module, but this is almost certainly a premature optimization but it has its own risks. Using del has no real effect, since those names would have been deleted as they went out of scope anyway.

Unihedron
  • 10,902
  • 13
  • 62
  • 72
d-coder
  • 12,813
  • 4
  • 26
  • 36
  • 1
    Indeed. Of course, when working in the interpreter's global namespace names aren't going to go out of scope, but so what. :) I guess it's also worth mentioning that what happens to the memory used by objects that have been garbage collected is implementation-dependant, but in most Python implementations the gc'ed memory merely goes back to the Python pool, it's **not** returned to the OS until the program exits. – PM 2Ring Oct 24 '14 at 10:04
  • @PM2Ring LOL :) I think so. From where do you refer for python ? – d-coder Oct 24 '14 at 10:33
  • 2
    Note that in CPython the GC is only needed to break reference cycles. If no references remain, an object *is* insta-removed from memory. So `del` **does** have a real effect here. – Martijn Pieters Oct 24 '14 at 11:23
  • @MartijnPieters, insta-removed? Is that a technical term? :) – Eryk Sun Oct 24 '14 at 11:41
  • 2
    @eryksun: yes, as defined by RFC 4042-bis2, of course! :-P – Martijn Pieters Oct 24 '14 at 11:44
  • @MartijnPieters LOL at RFC comment. I was pretty sure that CPython truly frees stuff, but I thought I'd leave it to someone who has used it to supply the details. :) Are there any other implementations that do that, though? I vaguely remember reading that the Windows version of some Python variant also returns stuff to the OS pool, but I've only ever used standard Python (and almost exclusively on Linux), so I don't remember the details. – PM 2Ring Oct 25 '14 at 05:03
  • @PM2Ring: Jython and IronPython use their respective runtime platform's garbage collector, so freeing can take a few cycles. – Martijn Pieters Oct 25 '14 at 08:07
  • the None option is very powerfull. If you have a big dataframe and you want to stop using space in memory just do: *myDataframe = None* – alepaff Dec 17 '21 at 22:59
3

This worked for me.

You need to run it twice once for globals followed by locals

for name in dir():
    if not name.startswith('_'):
        del globals()[name]

for name in dir():
    if not name.startswith('_'):
        del locals()[name]
Viswa
  • 55
  • 1
  • 1
  • 2
    The dictionary object obtained by `locals()` has no way to be modified, so using `del` on it is also invalid. – Andy Mar 22 '21 at 04:47
-1

you can use the del statement to delete variable in Python

example:

y = 10 del y

and in case you tried to use or refer to the deleted variable you will get error undefined.