Eu realmente não consigo pensar em nenhuma razão para o python precisar da del
palavra - chave (e a maioria das linguagens parece não ter uma palavra-chave semelhante). Por exemplo, em vez de excluir uma variável, pode-se apenas atribuir None
a ela. E ao excluir de um dicionário, um del
método pode ser adicionado.
Existe alguma razão para se manter del
em python ou é um vestígio dos dias de coleta de lixo pré-lixo do Python?
python
dictionary
python-internals
del
Jason Baker
fonte
fonte
del
.del
não é um vestígio da coleta pré-lixo, porque você sempre pode terused = None
. Sempre fazia sentido ter uma sintaxe específica para isso. Como agora temos GC cilíndrico, os casos em que você deseja usar são pequenos.ERASE
(variáveis matar específicos) eCLEAR
(matar todas as variáveis)Respostas:
Primeiramente, você pode deletar outras coisas além das variáveis locais
Ambos devem ser claramente úteis. Em segundo lugar, o uso
del
em uma variável local torna a intenção mais clara. Comparar:para
Sei que, no caso,
del foo
a intenção é remover a variável do escopo. Não está claro o quefoo = None
está fazendo isso. Se alguém acabou de atribuirfoo = None
eu poderia pensar que era um código morto. Mas eu instantaneamente sei o que alguém que codificadel foo
estava tentando fazer.fonte
del
usado em cálculos com muita memória, mas quando o vi, percebi imediatamente por que era necessário.del
para sinalizar intenção (como um comentário poderia fazer o mesmo sem aumentar o idioma), mas suponho que essa seja a melhor resposta.len()
função da mesma maneira. Se for esse o caso, a pergunta pode ter sido encerrada como opinião ou mesmo com base no gosto. O Python simplesmente tende a fornecer primitivas para operações básicas, em vez de depender de métodos.Existe esta parte do que
del
faz (da Referência da linguagem Python ):A atribuição
None
a um nome não remove a ligação do nome do espaço para nome.(Suponho que possa haver algum debate sobre se a remoção de uma ligação de nome é realmente útil , mas essa é outra questão.)
fonte
del
remove uma ligação de nome, como ele sugeriu atribuirNone
como alternativa.NameError
. Greg Hewgill faz essa mesma distinção. E é essa distinção que deixa clara a minha afirmação do que o pôster "claramente" entendeu.Um lugar que eu achei
del
útil é limpar variáveis estranhas nos loops de:Agora você pode ter certeza de que x será indefinido se você o usar fora do loop for.
fonte
del
linha aqui deve estar recuada (isto é, parte do loop)?NameError: name 'x' is not defined
se a lista estiver vazia.Excluir uma variável é diferente de defini-la como None
A exclusão de nomes de variáveis com
del
é provavelmente algo usado raramente, mas é algo que não poderia ser alcançado trivialmente sem uma palavra-chave. Se você pode criar um nome de variável escrevendoa=1
, é bom que você possa desfazê-lo teoricamente excluindo a.Isso pode facilitar a depuração em alguns casos, pois a tentativa de acessar uma variável excluída gera um NameError.
Você pode excluir atributos da instância de classe
Python permite escrever algo como:
Se você optar por adicionar atributos dinamicamente a uma instância de classe, certamente desejará desfazê-lo escrevendo
fonte
Há um exemplo específico de quando você deve usar
del
(pode haver outros, mas eu sei disso imediatamente) quando você está usandosys.exc_info()
para inspecionar uma exceção. Essa função retorna uma tupla, o tipo de exceção que foi gerada, a mensagem e um retorno.Os dois primeiros valores geralmente são suficientes para diagnosticar um erro e agir sobre ele, mas o terceiro contém toda a pilha de chamadas entre onde a exceção foi gerada e onde a exceção foi capturada. Em particular, se você fizer algo como
o retorno,
tb
acaba nos locais da pilha de chamadas, criando uma referência circular que não pode ser coletada como lixo. Assim, é importante fazer:para quebrar a referência circular. Em muitos casos em que você gostaria de chamar
sys.exc_info()
, como na magia da metaclasse, o traceback é útil, portanto, você deve limpá-lo antes de poder sair do manipulador de exceções. Se você não precisar do rastreamento, exclua-o imediatamente ou faça:Para evitar tudo isso junto.
fonte
Apenas outro pensamento.
Ao depurar aplicativos http em estruturas como o Django, a pilha de chamadas cheia de variáveis inúteis e bagunçadas usadas anteriormente, especialmente quando é uma lista muito longa, pode ser muito dolorosa para os desenvolvedores. portanto, nesse ponto, o controle de namespace pode ser útil.
fonte
Usar explicitamente "del" também é uma prática melhor do que atribuir uma variável a None. Se você tentar deletar uma variável que não existe, você receberá um erro de tempo de execução, mas se tentar definir uma variável que não exista como None, o Python silenciosamente definirá uma nova variável como None, deixando a variável que você queria excluído onde estava. Então, del irá ajudá-lo a detectar seus erros mais cedo
fonte
Para adicionar alguns pontos às respostas acima:
del x
A definição de
x
indicar -> o
(uma referênciar
apontando para um objetoo
), masdel x
muda emr
vez deo
. É uma operação na referência (ponteiro) ao objeto e não ao objeto associadox
. Distinguir entrer
eo
é a chave aqui.locals()
.globals()
sex
pertence lá.x
pertence e não para ondex
aponta. A única mudança física na memória é essa. Por exemplo, sex
estiver em um dicionário ou lista, ele (como referência) é removido de lá (e não necessariamente do pool de objetos). Neste exemplo, o dicionário ao qual ele pertence é o quadro da pilha (locals()
), sobrepostoglobals()
.fonte
Forçar o fechamento de um arquivo após o uso de numpy.load:
Um uso de nicho, talvez, mas achei útil ao usar
numpy.load
para ler um arquivo. De vez em quando eu atualizava o arquivo e precisava copiar um arquivo com o mesmo nome para o diretório.Eu costumava
del
liberar o arquivo e me permitir copiar o novo arquivo.Note que eu quero evitar o
with
gerenciador de contexto, pois estava brincando com gráficos na linha de comando e não queria pressionar muito a tecla Tab!Veja esta pergunta.
fonte
__del__()
método nos objetos de lixo é chamado ou mesmo se é chamado. Portanto, as APIs que não oferecem outra maneira de liberar recursos, além de esperar que o__del__()
método seja chamado algum tempo (logo após o objeto ser lixo), são quebradas em algum grau.del
é frequentemente visto em__init__.py
arquivos. Qualquer variável global definida em um__init__.py
arquivo é automaticamente "exportada" (será incluída em afrom module import *
). Uma maneira de evitar isso é definir__all__
, mas isso pode ficar confuso e nem todo mundo usa.Por exemplo, se você tivesse código
__init__.py
comoEntão seu módulo exportaria o
sys
nome. Você deveria escreverfonte
Como um exemplo do que
del
pode ser usado, acho útil em situações como esta:Estas duas funções podem estar em diferentes pacotes / módulos eo programador não precisa saber o argumento valor padrão
c
emf
realmente tem. Portanto, usando kwargs em combinação com del, você pode dizer "Quero o valor padrão em c", definindo-o como None (ou, neste caso, também o deixe).Você poderia fazer a mesma coisa com algo como:
No entanto, acho o exemplo anterior mais SECO e elegante.
fonte
Você pode usá-lo para remover um único elemento de uma matriz em vez da sintaxe da fatia
x[i:i+1]=[]
. Isso pode ser útil se, por exemplo, você estiver dentroos.walk
e desejar excluir um elemento no diretório Porém, eu não consideraria uma palavra-chave útil para isso, pois é possível criar um[].remove(index)
método (o.remove
método é realmente pesquisar e remover a primeira instância do valor).fonte
[].pop(index)
e[].remove(item)
. Não use a variável nomeada"index"
ao falar sobre valor, isso parecerá confuso.Eu achei
del
útil para o gerenciamento de memória pseudo-manual ao lidar com grandes dados com o Numpy. Por exemplo:Essa pode ser a diferença entre interromper um processo de trituração, à medida que o sistema muda como louco quando o GC Python não consegue acompanhar o funcionamento perfeitamente suave abaixo de um limite de memória fraco que deixa bastante espaço para usar a máquina para navegar. e codifique enquanto estiver trabalhando.
fonte
Eu acho que uma das razões pelas quais del tem sua própria sintaxe é que substituí-lo por uma função pode ser difícil em certos casos, uma vez que opera na ligação ou variável e não no valor que ele faz referência. Assim, se uma versão funcional de del fosse criada, um contexto precisaria ser passado. Del foo precisaria se tornar global (). Remove ('foo') ou locals (). Remove ('foo') que fica confuso e menos legível. Ainda assim, digo que se livrar de del seria bom, devido ao seu uso aparentemente raro. Mas remover recursos / falhas de idioma pode ser doloroso. Talvez o python 4 o remova :)
fonte
Eu gostaria de elaborar a resposta aceita para destacar a nuance entre definir uma variável como
None
versus removê-la comdel
:Dada a variável
foo = 'bar'
e a seguinte definição de função:Uma vez declarado inicialmente,
test_var(foo)
produzvariable tested true
conforme o esperado.Agora tente:
qual produz
variable tested false
.Compare esse comportamento com:
que agora aumenta
NameError: name 'foo' is not defined
.fonte
Ainda outro uso de nicho: no pyroot com ROOT5 ou ROOT6, "del" pode ser útil para remover um objeto python que se refere a um objeto C ++ não existente. Isso permite que a pesquisa dinâmica do pyroot encontre um objeto C ++ com nome idêntico e vincule-o ao nome do python. Então você pode ter um cenário como:
Felizmente, esse nicho será fechado com o gerenciamento de objetos mais saudável do ROOT7.
fonte
O comando "del" é muito útil para controlar dados em uma matriz, por exemplo:
Resultado:
['B', 'C', 'D']
fonte
Uma vez eu tive que usar:
porque usando apenas:
não liberou a porta serial com rapidez suficiente para abri-la imediatamente novamente. Com a lição, aprendi que isso
del
realmente significava: "GC now NOW! E espere até que esteja pronto", e isso é realmente útil em muitas situações. Claro, você pode ter umsystem.gc.del_this_and_wait_balbalbalba(obj)
.fonte
__del__()
sempre está errado no Python (embora eu não conheça os motivos desse design) e é melhor usar a API do gerenciador de contexto (awith
declaração).serial
módulo também funciona com o Jython para que seu hack não funcione lá!del é o equivalente a "unset" em muitas linguagens e como um ponto de referência cruzado que passa de outra linguagem para python. as pessoas tendem a procurar comandos que fazem a mesma coisa que costumavam fazer na primeira língua ... também definindo um var para "" ou nenhum realmente não remove o var do escopo .. apenas esvazia seu valor, o nome do var ainda estaria armazenado na memória ... por quê?!? em um script intensivo de memória ... mantendo o lixo por trás do seu simplesmente não, não e de qualquer maneira ... todas as línguas por aí têm alguma forma de uma função var "unset / delete" .. por que não python?
fonte
del
não invoca o coletor de lixo mais rapidamente do que= None
nem deixa o lixo para trás a longo prazo. Você pode querer desenterrar a coleta de lixo do Python.Todo objeto em python tem um identificador, Type, contagem de referência associada a ele, quando usamos del a contagem de referência é reduzida, quando a contagem de referência se torna zero, é um candidato em potencial à coleta de lixo. Isso diferencia o del quando comparado à configuração de um identificador como Nenhum. Em um caso posterior, significa simplesmente que o objeto é deixado de fora do estado selvagem (até ficarmos fora do escopo, nesse caso, a contagem é reduzida) e agora o identificador simplesmente aponta para outro objeto (localização da memória).
fonte