43 votes

`del` sur un paquet a une sorte de mémoire

del semble avoir la mémoire qui me énigmes. Voir la suivante:

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'

Des beaux. Voyons ce qui se passe si nous supprimons l'ensemble du paquet de maths:

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

Alors maintenant, les mathématiques lui-même s'en est allé, comme prévu.

Maintenant, nous allons importer les mathématiques à nouveau:

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'

Donc, en quelque sorte interactive python se souvient que les mathématiques.cos a été supprimé spécifiquement, même après que nous avons supprimé, l'ensemble du paquet de maths et importé à nouveau.

D'où vient python garde cette connaissance? Peut-on y avoir accès? Pouvons-nous changer?

62voto

deceze Points 200115

Un paquet n'est lu qu'une seule fois sur le disque, puis stocké en mémoire en tant que singleton mutable. La deuxième fois que vous l'importez, vous obtenez exactement le même singleton que celui que vous avez précédemment importé, et il lui manque toujours les cos . del math supprime simplement son nom local, il ne "sous-importe" pas le paquet dans l'ensemble de Python.

23voto

Jean-François Fabre Points 94672

Je dirais que le colis est toujours considéré comme importé. Donc exécuter import math nouveau juste redeclares le nom, mais avec l'ancien contenu.

Vous pouvez utiliser reload à assurez-vous que votre module est tout nouveau, sauf que certaines versions de python besoin pour supprimer l'entrée dans sys.modules , ce qui rend l'utilisation d' reload redondant:

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

(cette différence entre les différentes versions de python, reload et import sont discutés dans une question de suivi: Doit importlib.recharger restaurer un attribut supprimé en Python 3.6?)

15voto

RemcoGerlich Points 5676

del math ne supprime pas le paquet à tous, il supprime tout les nom local math dans le module en cours.

Comme tout autre objet, le cas échéant d'autres références pour le module math existe nulle part, alors il est conservé dans la mémoire.

Et en particulier, sys.modules est toujours un dictionnaire de tous les modules chargés, donc au moins il y a toujours une référence.

Edit: Mais il y a un moyen de recharger un module, imp.reload.

Malheureusement je ne peux pas faire fonctionner ce cas, rechargez les besoins du module random (probablement à créer une certaine partie de la compilation fichier Python), le module random besoins en math.cos, et il a disparu. Même avec l'importation d' random d'abord il n'y a pas d'erreur, mais math.cos ne réapparaît pas; je ne sais pas pourquoi, peut-être parce que c'est un builtin module.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X