Je ne peux pas vraiment penser à aucune raison pour laquelle python a besoin du del
mot - clé (et la plupart des langues semblent ne pas avoir de mot-clé similaire). Par exemple, plutôt que de supprimer une variable, on pourrait simplement lui affecter None
. Et lors de la suppression d'un dictionnaire, une del
méthode pourrait être ajoutée.
Y a-t-il une raison de rester del
en python, ou est-ce un vestige des jours de pré-collecte des ordures de Python?
python
dictionary
python-internals
del
Jason Baker
la source
la source
del
.del
n'est pas un vestige de la pré-collecte des ordures, car vous pourriez toujours l'avoirused = None
. Il est toujours logique d'avoir une syntaxe spécifique pour cela. Puisque nous avons maintenant le GC cylindrique, les cas où vous souhaitez utiliser l'un ou l'autre sont petits.ERASE
(tuer des variables spécifiques) etCLEAR
(tuer toutes les variables)Réponses:
Tout d'abord, vous pouvez supprimer d'autres choses en plus des variables locales
Les deux devraient être clairement utiles. Deuxièmement, l'utilisation
del
d'une variable locale rend l'intention plus claire. Comparer:à
Je sais dans le cas de
del foo
cela que l'intention est de retirer la variable de la portée. Ce n'est pas clair quifoo = None
fait ça. Si quelqu'un vient d'être assigné,foo = None
je pourrais penser que c'était du code mort. Mais je sais instantanément ce que quelqu'un qui codedel foo
essayait de faire.la source
del
utilisé dans les calculs gourmands en mémoire, mais quand je l'ai vu, j'ai réalisé immédiatement pourquoi c'était nécessaire.del
pour signaler l'intention (car un commentaire pourrait faire la même chose sans ajouter au langage), mais je suppose que c'est la meilleure réponse.len()
fonction de la même manière. Si tel est le cas, la question peut avoir été classée comme opinion ou même basée sur le goût. Python tend simplement à fournir des primitives pour les opérations de base au lieu de s'appuyer sur des méthodes.Il y a cette partie de ce que
del
fait (à partir de la référence du langage Python ):L'affectation
None
à un nom ne supprime pas la liaison du nom de l'espace de noms.(Je suppose qu'il pourrait y avoir un débat sur la question de savoir si la suppression d'une liaison de nom est réellement utile , mais c'est une autre question.)
la source
del
suppression d'un nom est supprimée car il a suggéré l'attributionNone
comme alternative.NameError
. Greg Hewgill fait cette distinction. Et c'est cette distinction qui rend votre affirmation de ce que l'affiche "clairement" comprise peu claire pour moi.Un endroit que j'ai trouvé
del
utile est de nettoyer les variables étrangères dans les boucles for:Vous pouvez maintenant être sûr que x ne sera pas défini si vous l'utilisez en dehors de la boucle for.
la source
del
ligne ici est-elle censée être en retrait (c'est-à-dire une partie de la boucle)?NameError: name 'x' is not defined
si la liste est vide.La suppression d'une variable est différente de sa définition sur Aucune
La suppression de noms de variables avec
del
est probablement quelque chose de rarement utilisé, mais c'est quelque chose qui ne pourrait pas être réalisé sans un mot-clé. Si vous pouvez créer un nom de variable en écrivanta=1
, il est bien que vous puissiez théoriquement l'annuler en supprimant a.Cela peut faciliter le débogage dans certains cas, car essayer d'accéder à une variable supprimée déclenchera une erreur NameError.
Vous pouvez supprimer des attributs d'instance de classe
Python vous permet d'écrire quelque chose comme:
Si vous choisissez d'ajouter dynamiquement des attributs à une instance de classe, vous voulez certainement pouvoir l'annuler en écrivant
la source
Il y a un exemple spécifique de quand vous devez utiliser
del
(il peut y en avoir d'autres, mais je connais celui-ci à part) lorsque vous utilisezsys.exc_info()
pour inspecter une exception. Cette fonction renvoie un tuple, le type d'exception qui a été déclenché, le message et une traceback.Les deux premières valeurs sont généralement suffisantes pour diagnostiquer une erreur et agir sur celle-ci, mais la troisième contient la pile d'appels entière entre l'endroit où l'exception a été levée et l'endroit où l'exception est interceptée. En particulier, si vous faites quelque chose comme
le traceback,
tb
se retrouve dans les sections locales de la pile d'appels, créant une référence circulaire qui ne peut pas être récupérée. Ainsi, il est important de faire:pour briser la référence circulaire. Dans de nombreux cas où vous voudriez appeler
sys.exc_info()
, comme avec la magie des métaclasses, le retraçage est utile, vous devez donc vous assurer de le nettoyer avant de pouvoir éventuellement quitter le gestionnaire d'exceptions. Si vous n'avez pas besoin du traçage, vous devez le supprimer immédiatement ou simplement:Pour éviter tout cela ensemble.
la source
Juste une autre pensée.
Lors du débogage d'applications http dans un framework comme Django, la pile d'appels remplie de variables inutiles et gâchées précédemment utilisées, en particulier lorsqu'il s'agit d'une liste très longue, pourrait être très pénible pour les développeurs. donc, à ce stade, le contrôle de l'espace de noms pourrait être utile.
la source
L'utilisation explicite de "del" est également une meilleure pratique que l'attribution d'une variable à None. Si vous essayez de supprimer une variable qui n'existe pas, vous obtiendrez une erreur d'exécution mais si vous essayez de définir une variable qui n'existe pas sur None, Python définira silencieusement une nouvelle variable sur None, en laissant la variable que vous voulait supprimé où il était. Alors del vous aidera à rattraper vos erreurs plus tôt
la source
Pour ajouter quelques points aux réponses ci-dessus:
del x
La définition de
x
indiquer -> o
(une référencer
pointant vers un objeto
) maisdel x
changer
plutôt queo
. Il s'agit d'une opération sur la référence (pointeur) à l'objet plutôt que sur l'objet associéx
. La distinction entrer
eto
est la clé ici.locals()
.globals()
six
appartient à cet emplacement.x
appartient, pas oùx
pointe. Le seul changement physique dans la mémoire est le suivant. Par exemple, si sex
trouve dans un dictionnaire ou une liste, il (comme référence) en est supprimé (et pas nécessairement du pool d'objets). Dans cet exemple, le dictionnairelocals()
auquel il appartient est le cadre de pile ( ), qui chevaucheglobals()
.la source
Forcer la fermeture d'un fichier après avoir utilisé numpy.load:
Un créneau d'utilisation peut-être mais je l'ai trouvé utile lors
numpy.load
de la lecture d'un fichier. De temps en temps, je mettais à jour le fichier et je devais copier un fichier du même nom dans le répertoire.J'ai utilisé
del
pour libérer le fichier et me permettre de copier dans le nouveau fichier.Remarque Je veux éviter le
with
gestionnaire de contexte car je jouais avec des tracés sur la ligne de commande et je ne voulais pas appuyer beaucoup sur tab!Voir cette question.
la source
__del__()
méthode sur les objets poubelle est appelée ou même si elle est appelée du tout. Ainsi, les API qui n'offrent aucun moyen de libérer des ressources autres que d'espérer que la__del__()
méthode soit appelée un certain temps (peu de temps après que l'objet est une ordure) sont cassées dans une certaine mesure.del
est souvent vu dans les__init__.py
fichiers. Toute variable globale définie dans un__init__.py
fichier est automatiquement "exportée" (elle sera incluse dans afrom module import *
). Une façon d'éviter cela est de définir__all__
, mais cela peut devenir compliqué et tout le monde ne l'utilise pas.Par exemple, si vous aviez du code
__init__.py
commeEnsuite, votre module exporterait le
sys
nom. Vous devriez plutôt écrirela source
À titre d'exemple de ce qui
del
peut être utilisé, je trouve cela utile dans des situations comme celle-ci:Ces deux fonctions peuvent être dans différents packages / modules et le programmeur n'a pas besoin de savoir quel argument de valeur par défaut
c
enf
ont fait. Donc, en utilisant kwargs en combinaison avec del, vous pouvez dire "Je veux la valeur par défaut sur c" en la définissant sur None (ou dans ce cas, laissez-la également).Vous pourriez faire la même chose avec quelque chose comme:
Cependant je trouve l'exemple précédent plus SEC et plus élégant.
la source
Vous pouvez l'utiliser pour supprimer un seul élément d'un tableau au lieu de la syntaxe de tranche
x[i:i+1]=[]
. Cela peut être utile si, par exemple, vous êtes dansos.walk
et souhaitez supprimer un élément du répertoire. Je ne considérerais pas un mot-clé utile pour cela, car on pourrait simplement créer une[].remove(index)
méthode (la.remove
méthode est en fait rechercher et supprimer la première instance de valeur).la source
[].pop(index)
et[].remove(item)
. N'utilisez pas de variable nommée"index"
lorsque vous parlez de valeur, cela semble déroutant.J'ai trouvé
del
utile pour la gestion de la mémoire pseudo-manuelle lors de la manipulation de grandes données avec Numpy. Par exemple:Cela peut être la différence entre l'arrêt brutal d'un script car le système échange comme un fou lorsque le GC Python ne peut pas suivre, et il fonctionne parfaitement en dessous d'un seuil de mémoire lâche qui laisse beaucoup d'espace pour utiliser la machine pour parcourir et le code pendant qu'il fonctionne.
la source
Je pense que l'une des raisons pour lesquelles del a sa propre syntaxe est que le remplacer par une fonction peut être difficile dans certains cas étant donné qu'il opère sur la liaison ou la variable et non sur la valeur à laquelle il fait référence. Ainsi, si une version de fonction de del devait être créée, un contexte devrait être transmis. Del foo devrait devenir des globaux (). et moins lisible. Je dis toujours que se débarrasser de del serait bien étant donné son utilisation apparemment rare. Mais supprimer les fonctionnalités / défauts du langage peut être douloureux. Peut-être que python 4 le supprimera :)
la source
Je voudrais développer la réponse acceptée pour souligner la nuance entre la définition d'une variable
None
et sa suppression avecdel
:Étant donné la variable
foo = 'bar'
et la définition de fonction suivante:Une fois initialement déclaré, le
test_var(foo)
rendementvariable tested true
est conforme aux attentes.Maintenant essaye:
qui cède
variable tested false
.Comparez ce comportement avec:
qui soulève maintenant
NameError: name 'foo' is not defined
.la source
Encore une autre utilisation de niche: dans pyroot avec ROOT5 ou ROOT6, "del" peut être utile pour supprimer un objet python qui faisait référence à un objet C ++ qui n'existe plus. Cela permet à la recherche dynamique de pyroot de trouver un objet C ++ portant le même nom et de le lier au nom de python. Vous pouvez donc avoir un scénario tel que:
Espérons que ce créneau sera fermé avec la gestion des objets plus saine de ROOT7.
la source
La commande "del" est très utile pour contrôler les données dans un tableau, par exemple:
Production:
['B', 'C', 'D']
la source
Une fois, j'ai dû utiliser:
car en utilisant uniquement:
n'a pas libéré le port série assez rapidement pour le rouvrir immédiatement. De cette leçon, j'ai appris que
del
cela signifiait vraiment: "GC this MAINTENANT! Et attendez qu'il soit fait" et c'est vraiment utile dans beaucoup de situations. Bien sûr, vous pouvez en avoir unsystem.gc.del_this_and_wait_balbalbalba(obj)
.la source
__del__()
est toujours mauvais en Python (je ne connais pas les raisons de cette conception, cependant) et il est préférable d'utiliser l'API du gestionnaire de contexte (lawith
déclaration).serial
module fonctionne également avec Jython afin que votre hack ne fonctionne pas là-bas!del est l'équivalent de "unset" dans de nombreuses langues et comme point de référence croisé passant d'une autre langue à python .. les gens ont tendance à chercher des commandes qui font la même chose qu'avant dans leur première langue ... un var à "" ou aucun ne supprime pas vraiment le var de la portée .. il vide juste sa valeur le nom du var lui-même serait toujours stocké en mémoire ... pourquoi?!? dans un script gourmand en mémoire..maintenant la corbeille derrière son juste un non non et de toute façon ... chaque langue là-bas a une certaine forme de fonction var "unset / delete "..pourquoi pas python?
la source
del
n'invoque pas le garbage collector plus rapidement que= None
, ni ne laissera non plus de déchets à long terme. Vous voudrez peut-être approfondir la collecte des ordures de Python.Chaque objet en python a un identifiant, Type, le nombre de références qui lui est associé, lorsque nous utilisons del le nombre de références est réduit, lorsque le nombre de références devient nul, il est un candidat potentiel pour récupérer les ordures. Cela différencie le del par rapport à la définition d'un identifiant sur Aucun. Dans un cas ultérieur, cela signifie simplement que l'objet est simplement laissé de côté (jusqu'à ce que nous soyons hors de portée, auquel cas le nombre est réduit) et simplement maintenant, l'identifiant pointe vers un autre objet (emplacement de la mémoire).
la source