Reputation: 4137
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
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
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
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