2

I am using Jupyter Notebook and want to delete all the variables created after a certain point. I am able to do it using a for-loop looping through dir() and comparing it to the checkpoint that I create at the cell using checkpoint = list(dir()).

My goal is to clear the environment without losing the libraries that I import in the beginning (which is where I create my checkpoint). Anything I want to retain further, I can add to the checkpoint list and delete the rest.

The issue is, I don't want to write the same for-loop again whenever I want to clear the variables. As soon as I wrap that loop in a function, it stops working. There is no error; but there is no effect either.

Loop:

for i in list(dir()):
    if i not in checkpoint:
        exec('del {}'.format(i))

The same loop wrapped in a function:

def clear_variables():
    for i in list(dir()):
        if i not in checkpoint:
            exec('del {}'.format(i))

The loop works. The function doesn't.

4
  • 2
    How about creating functions for the various steps in your notebook? This has two benefits: one, variables are limited to the scope of the function and two, it'll make your code easier to refactor (and probably to reuse). Commented Nov 21, 2019 at 10:04
  • @OliverW. This notebook is me taking notes while going through an online course. Which means there are many variables that just hold data and are useless after a certain point in course is over. I wanted to do it in a single notebook instead of creating many and thought clearing the environment often would make things easier. Commented Nov 21, 2019 at 10:14
  • 2
    Exec is already a bad idea to begin with. Putting it in a function scope just runs del in the function, which if course does nothing to the globals. Commented Nov 21, 2019 at 13:46
  • @MadPhysicist Yeah.. I figured that out just now. Also, dir() inside a function was returning the variables present inside the function itself. I have come up with a solution (it seems amateurish though). Could you tell me if I should post the solution or delete the question itself? Commented Nov 21, 2019 at 14:08

1 Answer 1

2

It sounds like you are trying to update your global dictionary. You can't safely delete values from a dictionary while you're iterating over it, so you can make a copy of the keys first:

def clear_setpoint(keep, globals=globals()):
    keep = set(keep)
    for key in list(globals.keys()):
        if key not in keep:
            del globals[key]

If your only goal is to preserve imported modules, you don't even need to create a checkpoint:

from types import ModuleType, FunctionType

def clear_all(globals=globals()):
    for key in list(globals.keys()):
        value = globals[key]
        if not isinstance(value, (ModuleType, FunctionType, type)) or \
              (isinstance(value, FunctionType, type) and value.__module__ == globals['__name__'] and value.__name__ != 'clear_all'):
            del globals[key]

This version will automatically delete anything that is not a function, module or class. Classes and functions that are in the current module, based on their __module__ attribute, are deleted as well. Other classes and functions are l And of course, you don't want to delete the function itself :)

kely to be imported, so are not deleted. This won't preserve imported constants, like if you do from math import pi. You can combine the two approaches to preserve imports like that.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. I got to the same solution. With a few more lines. This is concise. :)
Thank you. I think I can add another attribute to the function to contain a list of other objects I don't want deleted (like the example of pi) to handle exceptional cases.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.