b-fg
b-fg

Reputation: 4137

Delete python variables matching specifing name pattern

Is there a way to clear Python variables matching a specific name string pattern? For example, let:

a = 1
b = 2
ab = 3

So we can use some sort of del a* expression that would delete all variables which names start with a (a and ab in the example above).

Upvotes: 0

Views: 739

Answers (3)

Daniel
Daniel

Reputation: 12026

One could suggest any variation of the following:

def mydel(regexp):
    targets = globals().copy()
    for target in targets:
        if re.match(regexp, target):
            globals().pop(target)

This will update the globals() dictionary which keeps track of what variables are accessible.

Now, you asked about memory management, so the question remains whether removing a variable from the globals() dictionary would actually trigger it to be deleted. For this we can check that the lifetime of the object pointed to by the variable we deleted has actually ended. This can be done in cpython by importing ctypes.

import ctypes
h1, h2, h3 = 1, 2, 3
id_check = id(h1)

mydel(r'h.*')

Trying to use any of the variables shows that it is surely, as expected, not accessible:

h1
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/var/folders/81/h94bb5fx2cs6chrwgdsvn4cr0000gp/T/ipykernel_70978/1500632009.py in <module>
----> 1 h3

NameError: name 'h3' is not defined

However, if we use ctypes to query for the object id...

ctypes.cast(id_check, ctypes.py_object).value
1

Which shows that the memory has NOT been freed.

Upvotes: 1

Sujal Singh
Sujal Singh

Reputation: 582

It is possible, whether you should or not is something you have to consider but as mentioned by the comments it isn't good to do so.

There is a built-in function globals, as described in the documentation:

Return the dictionary implementing the current module namespace. For code within functions, this is set when the function is defined and remains the same regardless of where the function is called.

It's basically a dictionary with all your global variables (and other objects), so if you delete an item from this dictionary then that variable will be deleted.

Using the above information you can use the following code:

matches = [var for var in globals().keys() if var.startswith("a")]
for match in matches:
    del globals()[match]

You can change the matches list to whatever pattern you like, you could use regular expressions for more complicated deletes.

Upvotes: 4

Asger Weirs&#248;e
Asger Weirs&#248;e

Reputation: 350

Please don't do this. But yes it is possible.

By using the builtin function vars, it is of course also possible to use globals as @Sujal's answer states, to get a dictionary containing the variables in scope, then looping over them, and finding those that start with a, and deleting it. Then while we are at it, cleanup the variable v (because why not).

a = 2
b = 1
ab = 3

# Copy all vars and delete those that start with a
for v in vars().copy():
    if v.startswith('a'):
        del vars()[v]
    del v

print(b)
print(a)

This would produce

1
Traceback (most recent call last):
  File "[...]/main.py", line 12, in <module>
    print(a)
NameError: name 'a' is not defined

Upvotes: 1

Related Questions