9

I often use the Python Console for running some lines of code and I also use some prints for checking the validity of the results.

If I run this sample code:

a = 2
b = 4
res = a + b
print res

it will print the value of the res variable in the Python Console. However, if I then close the script tab, the res variable is still there. This means that, if I type print res in the Python Console, it will still return the last stored value.

I know that I can type:

del res

from the Python Console for deleting it. In fact, if I then type print res, I get:

NameError: name 'res' is not defined

as expected, but this is useful only when dealing with one or two variables and if I remember the names of these variables.


After a few searches, I found these questions:

How to clear python console in QGIS?

Clearing Python Console in QGIS using Python Command

but their answers only explain how to clear the Python Console and not how to delete the variables.


Is there a programmatic way for deleting all the variables stored during the current QGIS session?

4 Answers 4

9

In addition to @bcollins answer, if you want to change your variables you have defined inside the QGIS python console you can try this approach:

Define a variable which holds all variables before you start programming:

my_dir = dir()

Do your magic with gis, for example:

 my_variable = 42
 my_other_variable = "foo"

Then do something like this:

for varis in dir():
   if varis not in my_dir and varis != "my_dir":
        print varis 
        exec("%s = None" % str(varis)) # set them to None 

This way you get the all the variables which are NOT in my_dir and don't remove any other variables that were added by QGIS.

Update: With the suggestion of @jon_two I try to combine the method of @bcollins and mine. This would be something like:

## after you finished your magic
my_new_dir = list(dir())
for varis in my_new_dir:
   if varis not in my_dir and varis != "my_dir":
        del locals()[varis]
5
  • Which should be the expected result?
    – mgri
    Commented May 5, 2017 at 10:12
  • the expected result would be, that when you typ in for example 'my_variable', that it returns None, but the variable name would still exist. I though your aim is to free hd space. if not you could try @bcollins approach with 'del locals()[v]'
    – LaughU
    Commented May 5, 2017 at 10:48
  • I think a combination of this and @bcollins approach would be best, though don't forget to take a copy of locals/dir otherwise it will keep updating as you cycle through it. my_dir = list(dir()) or my_locals = dict(locals()).
    – jon_two
    Commented May 5, 2017 at 11:31
  • @LaughU, thanks for the edit! Your approach compares the initial dir() with the final dir() and seems to do the trick independently from the name and the numbers of the variables involved. Even if this is more a workaround than a direct method, it is enough for me. Also, +1 for the perseverance.
    – mgri
    Commented May 5, 2017 at 12:29
  • 2
    @LaughU my_new_dir = dir() is just giving you a reference to dir(), so if you add a new local variable, it will also be added to my_new_dir. Using my_new_dir = list(dir()) gives you a snapshot of dir() that will not be updated when variables are added to/deleted from local scope.
    – jon_two
    Commented May 5, 2017 at 12:40
6

There are a couple of builtin functions you should consider for this.

dir() will gives you the list of in scope variables
globals() will give you a dictionary of global variables
locals() will give you a dictionary of local variables

but you may run into trouble because you could inadvertently delete some variables that QGIS sets. So something like this could get you started:

>>> my_var_res = 4
>>> my_vars = [v for v in locals().keys() if v.startswith('my_var')]
['my_var_res']
>>> for v in my_vars:
        del locals()[v]

I'm not claiming this is a good thing to do, just that it is possible

1
  • Thanks for the answer, but probably this doesn't solve the issue. In this way, I need to know the name of the variable for using startswith() and doesn't seems a programmatic way for solving the problem. Or am I wrong?
    – mgri
    Commented May 5, 2017 at 9:53
6

A method which I used a while ago was to begin each variable name with an underscore ("_"). As there are no other variables beginning with a single underscore (only double), you can search for all these variables and delete them accordingly:

# Define user variables
_foo1 = "Hello world"
_foo2 = "bar"
_foo3 = {"1":"a", "2":"b"}
_foo4 = "1+1"

# Create list containing user variables
my_vars = []
for var in dir():
    if var.startswith('_') and not var.startswith('__'):
        my_vars.append(var)

# Delete specific user variable
for x in my_vars:
    if '_foo1' in x:
        del globals()[x]

# Delete all user variables
for x in my_vars:
    del globals()[x]
3
  • 1
    Thanks Joseph, but I think that solution the by @LaughU could be more versatile because it avoids the using of the underscore for all the variables involved.
    – mgri
    Commented May 5, 2017 at 12:31
  • 1
    @mgri - Most welcome and I agree, I found it quite a pain for having to constantly add an underscore for each variable. Fortunately, I didn't have to work with this for very long :)
    – Joseph
    Commented May 5, 2017 at 12:37
  • As you can imagine, my question was more a curiosity than a real need. =)
    – mgri
    Commented May 5, 2017 at 12:44
2

You may try the following for globals

At the beginning of the session, store keys from your global context e.g

myglobals = set(globals().keys())

Later, to know what you need to clean, you will get the difference method from the set using

set(globals().keys()).difference(myglobals)

To remove all globals variables, except myglobals used to keep state info in your PyQGIS console, do

for g in set(globals().keys()).difference(myglobals):
    if g != 'myglobals':
        del globals()[g]

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.