Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`del` on a package has some kind of memory

del seems to have some memory which puzzles me. See the following:

In [1]: import math

In [2]: math.cos(0)
Out[2]: 1.0

In [3]: del math.cos

In [4]: math.cos(0)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-9cdcc157d079> in <module>()
----> 1 math.cos(0)

AttributeError: module 'math' has no attribute 'cos'

Fine. Let's see what happens if we delete the whole math package:

In [5]: del math

In [6]: math.cos(0)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-6-9cdcc157d079> in <module>()
----> 1 math.cos(0)

NameError: name 'math' is not defined

So now math itself is gone, as expected.

Now let's import math again:

In [7]: import math

In [8]: math.cos(0)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-9cdcc157d079> in <module>()
----> 1 math.cos(0)

AttributeError: module 'math' has no attribute 'cos'

So somehow interactive python remembers that math.cos was deleted specifically even after we deleted the whole math package and imported it again.

Where does python keeps this knowledge? Can we access it? Can we change it?

like image 331
Aguy Avatar asked Feb 15 '18 14:02

Aguy


People also ask

Does Del free up memory?

The del statement removes the variable from the namespace, but it does not necessarily clear it from memory. Therefore, after deleting the variable using the del statement, we can use the gc. collect() method to clear the variable from memory.

What is Python memory?

Memory management in Python involves a private heap containing all Python objects and data structures. The management of this private heap is ensured internally by the Python memory manager.

Which is the correct way to deallocate memory in Python?

Python's memory allocation and deallocation method is automatic. The user does not have to preallocate or deallocate memory by hand as one has to when using dynamic memory allocation in languages such as C or C++. Python uses two strategies for memory allocation reference counting and garbage collection.


2 Answers

A package is only read from disk once and then stored in memory as mutable singleton. The second time you import it you get the exact same singleton you have previously imported, and it's still missing its cos. del math merely deletes the local name for it, it doesn't "unimport" the package from Python overall.

like image 50
deceze Avatar answered Oct 09 '22 23:10

deceze


I would say that the package is still seen as imported. So performing import math again just redeclares the name, but with old contents.

You could use reload to make sure your module is whole again, except that some versions of python require to remove the entry in sys.modules as well, which makes the use of reload redundant:

import math
del math.cos
del math
sys.modules.pop("math")   # remove from loaded modules
import math
print(math.cos(0))  # 1.0

(this difference between various python versions, reload and import are discussed in a follow-up question: Should importlib.reload restore a deleted attribute in Python 3.6?)

like image 23
Jean-François Fabre Avatar answered Oct 09 '22 23:10

Jean-François Fabre