python - notebook - jupyter anaconda download
`del` en un paquete tiene algĂșn tipo de memoria (3)
Un paquete solo se lee del disco una vez y luego se almacena en la memoria como singleton mutable. La segunda vez que lo importas obtienes el mismo singleton exactamente que has importado previamente, y aún le falta su cos
. del math
simplemente borra el nombre local, no "desimporta" el paquete de Python en general.
del
parece tener algo de memoria que me desconcierta. Vea lo siguiente:
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''
Multa. Veamos qué pasa si eliminamos todo el paquete de matemáticas:
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
Entonces, ahora las matemáticas se han ido, como se esperaba.
Ahora vamos a importar las matemáticas de nuevo:
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''
Entonces, de alguna manera, python interactivo recuerda que math.cos se eliminó específicamente incluso después de eliminar todo el paquete matemático y volver a importarlo.
¿Dónde guarda Python este conocimiento? ¿Podemos acceder a ella? ¿Podemos cambiarlo?
Yo diría que el paquete todavía se ve como importado. Entonces, la realización de import math
solo redeclara el nombre, pero con contenido antiguo.
Puede utilizar la reload
para asegurarse de que su módulo esté completo de nuevo, excepto que algunas versiones de python también requieren eliminar la entrada en sys.modules
, lo que hace que el uso de la reload
redundante:
import math
del math.cos
del math
sys.modules.pop("math") # remove from loaded modules
import math
print(math.cos(0)) # 1.0
(Esta diferencia entre varias versiones de Python, reload
e import
se analiza en una pregunta de seguimiento: ¿Debería importlib.reload restaurar un atributo eliminado en Python 3.6? )
del math
no elimina el paquete en absoluto, simplemente borra el nombre local math
en el módulo actual.
Al igual que cualquier otro objeto, si existen otras referencias al módulo matemático en cualquier lugar, entonces se mantiene en la memoria.
Y, en particular, sys.modules
es siempre un diccionario de todos los módulos cargados, por lo que siempre hay una referencia allí.
Editar: Pero hay una manera de volver a cargar un módulo, imp.reload
.
Desafortunadamente no puedo hacer que funcione para este caso, la recarga necesita el módulo aleatorio (probablemente para crear una parte del archivo Python compilado), el módulo aleatorio necesita math.cos
, y se ha ido. Incluso importando primero al random
no hay ningún error, pero math.cos
no vuelve a aparecer; No sé por qué, tal vez porque es un módulo integrado.