Por que deletar objetos de cursor / linha do ArcPy?

8

Alguém pode me ajudar a entender o que as duas últimas linhas deste código fazem:

import arcpy
arcpy.env.workspace = "c:/esripress/python/data/exercise07"
arcpy.env.overwriteOutput = True

copy = arcpy.CopyFeatures_management("airports.shp","Results/airports.shp")
fc = "Results/airports.shp"

cursor = arcpy.da.UpdateCursor(fc, ["STATE"], ' "STATE" <> \'AK\'')
for row in cursor:
    row[0] = "AK"
    cursor.updateRow(row)
del row
del cursor

Eu entendo que a função loop passa por cada registro que não tem um valor de 'AK' e atribui a esse registro um valor de "AK". Mas o que eu não entendo é o que o del rowe del cursordeve fazer.

Gabe
fonte
2
Aliás este código provavelmente corrompe o Statevalor de qualquer aeroporto que não foi no Alasca
Stephen Chumbo
3
Stephen escreveu uma boa resposta, no entanto, não esclareceu por que é importante liberar (excluir) objetos de linha / cursor. Um cursor aberto ou objeto de linha deixa um bloqueio na classe de recurso, o que causará problemas ao tentar fazer alterações na classe de recurso até que a sessão que retenha os bloqueios seja encerrada, geralmente fechando o aplicativo, mas pode ser tão grave quanto reiniciar o computador . Como você tem apenas um campo, ele não precisa ser uma lista (apenas 'state', não ['state'], mas isso não o interromperá; no entanto, substituirá qualquer estado que não seja 'AK' com "AK" como Stephen disse.
Michael Stimson
Obrigado pela sua contribuição, tudo o que vocês disseram fez todo o sentido. * Observe que o shapefile de aeroportos é de aeroportos em AK, eu estava preenchendo registros que não tinham valor para STATE.
Gabe

Respostas:

13

Essas são relíquias de um estilo anterior de arcpycursores. del row, cursorforam utilizados anteriormente para clean-up após o script foi executado, excluindo o rowe cursorobjetos. Agora, o uso adequado é envolver o cursor em uma withinstrução, que abre e fecha os objetos de linha e cursor, da seguinte maneira:

import arcpy
arcpy.env.workspace = "c:/esripress/python/data/exercise07"
arcpy.env.overwriteOutput = True

copy = arcpy.CopyFeatures_management("airports.shp","Results/airports.shp")
fc = "Results/airports.shp"

with arcpy.da.UpdateCursor(fc, ["STATE"], ' "STATE" <> \'AK\'') as cursor:
    for row in cursor:
        row[0] = "AK"
        cursor.updateRow(row)
Aaron
fonte
1
Sua resposta não está totalmente correta. Você ainda pode (e precisa, em alguns casos) usar o método antigo de criar o objeto do servidor e excluí-lo quando terminar. Por exemplo, para operações de inserção, às vezes é mais fácil fazê-lo dessa maneira ( pro.arcgis.com/en/pro-app/arcpy/data-access/… ). A principal vantagem da instrução with é que ela remove automaticamente o bloqueio nos dados se a operação falhar, o que o outro método não faz. Criar cursor - erro - pula a parte del e seus dados são bloqueados.
PhilippNagel 01/09
1
@PhilippNagel quando você precisaria usar o método antigo de criação de cursores?
Squanchy
1
Agora que penso nisso, não tenho certeza do que estava pensando naquela época.
PhilippNagel
Na página UpdateCursor "Os cursores de atualização também oferecem suporte a instruções para redefinir a iteração e ajudam na remoção de bloqueios. No entanto, o uso de uma instrução del para excluir o objeto ou envolver o cursor em uma função para que o objeto do cursor fique fora do escopo deve ser considerado como proteger contra todos os casos de bloqueio ". Meu entendimento disso, em outras palavras: para ter certeza de que algo não está travando, é melhor usar "del row, cursor". Ou você pode envolvê-lo em função para que, com o fim da função, todo o escopo local seja excluído automaticamente.
Miro