Se é melhor abrir cursores usando uma instrução with para garantir que ela seja excluída, da seguinte maneira:
with arcpy.da.UpdateCursor(fc,fields) as cursor:
Então, se um cursor for usado como iterável em uma compreensão como esta:
d = {k:v for (k,v) in arcpy.da.SearchCursor(fc,fields)}
É necessário excluir o cursor depois de usá-lo na compreensão?
da
cursores: sgillies.net/2011/02/01/01/get-with-it.html e help.arcgis.com/ pt-br / arcgisdesktop / 10.0 / help / index.html # //… . Em particular, veja os comentários de @JasonScheirer na parte inferior do primeiro link.Respostas:
Se é absolutamente necessário, é a pergunta errada a ser feita. A questão é se é uma boa ideia.
Como regra na programação, você deve evitar fazer coisas estranhas e usar a melhor ferramenta para o trabalho . Se algo tiver uma maneira explícita de liberar recursos, apenas torne a versão explícita e pronto:
O que você pode não estar ciente é que a
with
cláusula realmente chama lógica adicional. Umawith
cláusula requer um gerenciador de contexto, que deve ter um método__enter__
(chamado quando o bloco é inserido) e__exit__
(chamado quando o bloco é encerrado). Em particular, o__exit__
método é chamado independentemente da ocorrência de uma exceção, garantindo que o programa sempre libere o recurso mesmo com erro. Isso fornece ao seu código uma documentação explícita de quando um recurso é adquirido e quando é lançado, além de garantir que um recurso possa ser liberado o mais rápido possível.Por outro lado, você não pode realmente depender do tempo de execução para fechá-lo magicamente imediatamente para você. Isso ocorre porque a maneira como ele é fechado é invocando o destruidor do objeto, o que pode ou não acontecer imediatamente. O Python não oferece nenhuma garantia sobre quando um destruidor é chamado, apenas que será eventualmente quando o objeto for coletado de lixo. (Veja aqui .) Atualmente, o Python é implementado para que ocorra assim que não houver mais uma referência a um objeto. Mas é fácil propagar acidentalmente referências a um objeto, e o tempo de execução do Python pode mudar.
Considere também a manutenção a longo prazo. Não há nenhuma referência a longo prazo para isso agora, mas o que acontece em 6 meses quando você precisa modificar o código de modo que não é uma referência? E se alguém fizer isso? A pessoa que está fazendo a alteração pode não pensar em mudar para um
with
bloco, já que ainda não existe um. Crie um hábito de limpar seus recursos e você terá muito menos problemas com ele.Deseja realmente vincular seu código aos detalhes de implementação da coleta de lixo? Deseja ter que pensar constantemente se você pode estar propagando acidentalmente uma referência por uma exceção? Não você não. Imagine se isso aconteceu quando o script foi chamado no ArcMap. O usuário seria forçado a fechar todo o processo apenas para liberar o arquivo. Portanto, não se coloque nessa posição. Libere o recurso explicitamente. Salvar uma linha de código não vale os riscos de problemas que ela pode causar. Os gerenciadores de contexto são o mecanismo padrão para adquirir e liberar recursos no Python, e eles fazem isso muito bem.
O ponto principal é que não divulgá-lo explicitamente é uma má ideia.
Isso, é claro, pressupõe que o código tenha alguma possibilidade de afetar outra pessoa, como colocá-lo em um script que outra pessoa precisará executar ou manter ou pode atrasar a entrega do seu trabalho se você precisar fechar o ArcMap até o fim, porque você não pode salvar suas alterações. Se você é o único que será impactado por um problema, então, por todos os meios, enfrente as boas práticas o quanto quiser.
fonte
Não, não é necessário excluir um
cursor
depois de usá-lo em uma compreensão. Acursor
é uma instância de uma classe, que é um objeto (tudo em python é um objeto). Toda sessão python possui umanamespace
que contém referências a todos os objetos da sessão - pense nela como um dicionário em que as chaves são referências a cada objeto e os valores são os próprios objetos. Quando a 'contagem de referência' - o número de chaves que se referem a esse objeto - cai para zero, o objeto é removido e a memória re-alocada . Quando você usa acursor
em uma compreensão, não há referência a esse objeto no espaço para nome. Após a compreensão, o objeto será excluído.Não há entrada no espaço para nome e, portanto, não é necessário excluir nada. ESRI também ilustra essa sintaxe no exemplo 2, aqui .
Para esclarecer melhor, se você executar:
Você verá um arquivo .lock aparecer no diretório (verifique seu gerenciador de arquivos). A referência ao cursor é
a
, o que fará ocursor
(e, portanto, o bloqueio) persistir até quea
seja excluído. Então, quando você executa:A entrada no espaço para nome será removida e o bloqueio será liberado (o arquivo .lock desaparecerá). Se você executar:
Você não verá um arquivo de bloqueio ou ele desaparecerá quando o comando for concluído. Sem uma entrada no espaço para nome, o
cursor
não é persistente.t
refere-se à lista que você acabou de criar, não aocursor
usado para criá-la.Para resumir, você só precisa se preocupar em excluir
cursors
quando eles têm uma referência no espaço para nome (ou seja, quando você os atribuiu a uma variável, comoa
no exemplo acima).fonte
Bloquear com cursores arcpy.da é praticamente o mesmo que bloquear com os cursores arcpy originais.
Após testar seu código, e como Gberard apontou, não há referência ao cursor após o término da compreensão.
Além disso, não há bloqueios na classe de recurso após o término da compreensão.
fonte