How to Delete Created Variables, Functions, etc from the Memory of the Interpreter

Is there a way to delete created variables, functions, etc from the memory of the interpreter?

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.

Clear variable in python

What's wrong with self.left = None?

How do I clear all variables in the middle of a Python script?

The following sequence of commands does remove every name from the current module:

>>> import sys
>>> sys.modules[__name__].__dict__.clear()

I doubt you actually DO want to do this, because "every name" includes all built-ins, so there's not much you can do after such a total wipe-out. Remember, in Python there is really no such thing as a "variable" -- there are objects, of many kinds (including modules, functions, class, numbers, strings, ...), and there are names, bound to objects; what the sequence does is remove every name from a module (the corresponding objects go away if and only if every reference to them has just been removed).

Maybe you want to be more selective, but it's hard to guess exactly what you mean unless you want to be more specific. But, just to give an example:

>>> import sys
>>> this = sys.modules[__name__]
>>> for n in dir():
... if n[0]!='_': delattr(this, n)
...
>>>

This sequence leaves alone names that are private or magical, including the __builtins__ special name which houses all built-in names. So, built-ins still work -- for example:

>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'n']
>>>

As you see, name n (the control variable in that for) also happens to stick around (as it's re-bound in the for clause every time through), so it might be better to name that control variable _, for example, to clearly show "it's special" (plus, in the interactive interpreter, name _ is re-bound anyway after every complete expression entered at the prompt, to the value of that expression, so it won't stick around for long;-).

Anyway, once you have determined exactly what it is you want to do, it's not hard to define a function for the purpose and put it in your start-up file (if you want it only in interactive sessions) or site-customize file (if you want it in every script).

Remove function of R in Python

If I understand correctly, you are looking for the del function:

>>> df = pd.DataFrame()
>>> df
Empty DataFrame
Columns: []
Index: []
>>> del df
>>> df
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'df' is not defined

Deleting variables after use during assignment

there would ideally be a solution that only took up the size of at most two of the variables in memory.

del is not often needed in Python. The repetition is a code smell. Don't Repeat Yourself (DRY principle). You can remove the repetition by using a loop.

def forward(self, A):
for _ in range(2):
Z = layer(A)
A = activation(Z)
return A

You'd be re-using the two variables A and Z.

You can compress this further by nesting the calls, which removes the Z altogether.

def forward(self, A):
for _ in range(2):
A = activation(layer(A))
return A

If you're functionally inclined, this pattern is known as a "reduce" (sometimes also called a "fold"). This may be less "Pythonic", but the functional style is still pretty commonly used in Python code.

from functools import reduce

def forward(self, X):
return reduce(lambda A, _: activation(layer(A)), range(2), X)

Or even,

def forward(self, X):
return reduce(lambda x, f: f(x), [layer, activation]*2, X)

The popular toolz library also implements this pattern

from toolz.functoolz import thread_first

def forward(self, X):
return thread_first(X, layer, activation, layer, activation)

No intermediate variables required, but you can add comments if it makes you feel better.

def forward(self, X):
return thread_first(
X, # A0
layer, # Z1
activation, # A1
layer, # Z2
activation, # A2
)

These aren't enforced or anything.


In fact, the variables are not required at all, save for the parameter.

def forward(self, X):
return activate(layer(activate(layer(X))))

The function really is that simple, and the fuss about variable names seems to be over-complicating it.

For just two layers, this is probably OK, but the looping/reducing version makes it easier to add more layers later by updating the range() argument, which could even be another parameter to the .forward() method.


could you create a function that does the deletion and assignment (given scoping limitations) and what's the efficiency tradeoff there?

You can't really delete locals except with del (or when they go out of scope). But instead of locals, you could make your own namespace. This is backed by a dict, which is only slightly less efficient than locals, not enough to matter here.

from types import SimpleNamespace

class MonoNamespace(SimpleNamespace):
"""A namespace that holds only one attribute at a time."""
def __setattr__(self, name, value):
vars(self).clear()
vars(self)[name] = value

def forward(self, X):
ns = MonoNamespace(A0=X)
ns.Z1 = layer(ns.A0)
ns.A1 = activation(ns.Z1)
ns.Z2 = layer(ns.A1)
ns.A2 = activation(ns.Z2)
return ns.A2

Removing a variable ending with string pattern

As an alternative method, but which would solve your problem. you could make use of a dictionary.
So if you keep all your temporary objects in a dictionary, you would need to only delete that.

temp_dict = {'variable1_tmp': 1234, 'variable2_tmp': 'hello'}
# remove only one temp
del temp_dict['variable1_tmp']
# remove all temp
del temp_dict

Although that is not dynamically deleting variables, as you asked.
Hopefully that might suit your use case anyway.



Related Topics



Leave a reply



Submit