<\/HEAD>
Esta é a primeira parte de uma série em múltiplas partes sobre ArcPy cursors; particularmente, trabalhando com ArcPy cursors como objetos iteráveis em Python. A primeira parte da série<\/STRONG> analisa alguns dos componentes importantes da iteração em Python. A segunda parte da série <\/A>analisa a iteração e o looping sobre ArcPy Data Access cursors. A terceira parte da série <\/A>analisa o uso de várias funções built-in do Python e itertool com ArcPy Data Access cursors. A quarta parte da série irá analisar o uso de geradores ou expressões geradoras para separar a lógica de seleção ou filtragem para reutilização de código. A quinta ou as partes seguintes são desconhecidas neste momento.<\/EM><\/P><\/P>
Esta e as próximas séries de posts no blog focam nos
ArcPy Data Access <\/A>cursors no contexto da iteração, daí o título da série. Agora, pode parecer bobo falar sobre cursors iteráveis já que um cursor é basicamente inútil sem iteração, mas minha experiência scriptando com ArcPy cursors e respondendo perguntas no GeoNet me motivou a compartilhar algumas formas Pythonicas de pensar e trabalhar com cursors.<\/P><\/P>
Ao falar sobre iteração em Python, existem inúmeros termos e expressões que podem ser relevantes para uma discussão. Cinco termos que acredito serem especialmente importantes, e relevantes para esta série de posts no blog, são:<\/P>
Glossário<\/A><\/SPAN><\/P>generator<\/STRONG><\/P>Uma função que retorna um iterator. Parece uma função normal exceto que contém declarações
yield<\/SPAN> <\/A>para produzir uma série de valores utilizáveis em um for-loop ou que podem ser recuperados um por vez com a função next()<\/A><\/SPAN>. Cada yield<\/SPAN> <\/A>suspende temporariamente o processamento, lembrando o estado da execução (incluindo variáveis locais e try-statements pendentes). Quando o generator retoma, ele continua de onde parou (em contraste com funções que começam do zero a cada invocação).<\/P><\/P>generator expression<\/STRONG><\/P>Uma expressão que retorna um iterator. Parece uma expressão normal seguida por uma expressão for<\/SPAN> <\/A>definindo uma variável de loop, intervalo, e uma expressão opcional if<\/A><\/SPAN>. A expressão combinada gera valores para uma função envolvente:<\/P>>><\/SPAN>><\/SPAN> sum(<\/SPAN>i*< \/span>i for< \/span> i in< \/span> range(< \/span>10< \/span>)< \/span>)< \/span> # soma dos quadrados 0, 1, 4, ... 81< \/span>
285< \/span>
< \/span>< \/span>< \/SPAN>< \/CODE>< \/PRE>< \/TD>< \/TR>< \/TBODY>< \/TABLE>< \/BLOCKQUOTE>< P >< \/ P >< P >< STRONG >iterable< \/STRONG >< \/ P >< P style = "margin-left: 30px;" >Um objeto capaz de retornar seus membros um por vez. Exemplos de iterables incluem todos os tipos de sequência (como < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /functions.html#list" rel = "nofollow noopener noreferrer" target = "_blank" >list< \/ A >< \/ SPAN >, < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /functions.html#str" rel = "nofollow noopener noreferrer" target = "_blank" >str< \/ A >< \/ SPAN >, e < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /functions.html#tuple" rel = "nofollow noopener noreferrer" target = "_blank" >tuple< \/ A >< \/ SPAN >) e alguns tipos não-sequência como < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /stdtypes.html#dict" rel = "nofollow noopener noreferrer" target = "_blank" >dict< \/ A >< \/ SPAN > e < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /functions.html#file" rel = "nofollow noopener noreferrer" target = "_blank" >file< \/ A > < \/ SPAN >e objetos de quaisquer classes que você definir com um método < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /reference\ /datamodel.html#object.__iter__" rel = "nofollow noopener noreferrer" target = "_blank" >__iter__()< \/ A >< \/ SPAN > ou < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /reference\ /datamodel.html#object.__getitem__" rel = "nofollow noopener noreferrer" target = "_blank" >__getitem__()< \/ A >< \/ SPAN >. Iterables podem ser usados em um loop < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /reference\ /compound_stmts.html#for" rel = "nofollow noopener noreferrer" target = "_blank" >for< \/ A >< \/ SPAN > e em muitos outros lugares onde uma sequência é necessária (< SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /functions.html#zip" rel = "nofollow noopener noreferrer" target = "_blank" >zip()< \/ A >< \/ SPAN >, < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \/docs.python.org\ /2\ /library\ /functions.html#map" rel = "nofollow noopener noreferrer" target = "_blank" >map()< \/ A >< \/ SPAN >, ...). Quando um objeto iterable é passado como argumento para a função built-in < SPAN style = "font-family: courier new,courier;" >< A href = "https:\/ \ /docs.python.org\ /2\ /library\ /functions.html#iter" rel = "nofollow noopener noreferrer" target = "_blank" >iter()< \ /A >< \ /SPAM>, ele retorna um iterator para o objeto. Este iterator é bom para uma passagem sobre o conjunto de valores. Ao usar iterables, geralmente não é necessário chamar < SPAN style= courier new,courier;">
iter() função ou use-a em um loop for. Tentar isso com um iterador apenas retornará o mesmo objeto iterador esgotado usado na passagem de iteração anterior, fazendo parecer que é um contêiner vazio.
sequência
Um iterable que suporta acesso eficiente a elementos usando índices inteiros via o método especial __getitem__() e define um método len() que retorna o comprimento da sequência. Alguns tipos de sequência embutidos são list, str, tuple, e unicode. Note que dict também suporta __getitem__() e __len__(), mas é considerado um mapeamento em vez de uma sequência porque as buscas usam chaves arbitrárias immutable em vez de inteiros.
Comparado ao antigo glossário do ArcGIS Resources, agora renomeado para GIS Dictionary e hospedado no Esri Support, o Python Glossary é bastante substancial. Dito isso, o Python Glossary também é um daqueles que faz sentido para pessoas que já conhecem a resposta, mas pode ser um pouco difícil para quem é novo na linguagem.
Analisando o trecho do glossário acima, pode-se perceber que alguns métodos especiais/mágicos/dunder são muito importantes para iteração: __iter__(), __getitem__(), e next() (ou __next__() se estiver trabalhando com Python 3.x). Também existem algumas funções embutidas importantes que interagem com esses métodos: iter() e next(). E por último, mas não menos importante, o loop for e a instrução yield. Existem mais métodos, funções, instruções e estruturas de controle envolvidas na iteração, mas os mencionados são centrais para qualquer discussão. Para os leitores interessados em aprender mais sobre iteradores, geradores, sequências, etc...; há inúmeros guias introdutórios e tutoriais já escritos e que estão a apenas uma rápida pesquisa no Google de distância.
Listas são tão comuns em Python, e os novatos na linguagem têm contato com elas tão cedo, que usarei exemplos de listas Python para contexto junto com os exemplos do cursor de busca ArcPy Data Access. O Python Glossary afirma que uma lista é "uma sequência Python embutida", e uma sequência é "um iterable que suporta acesso eficiente a elementos usando índices inteiros...." A documentação do ArcPy Data Access SearchCursor diz que o cursor de busca "retorna um iterador de tuplas." Como iteradores também são iterables, tem-se a sensação de que funções embutidas e expressões comumente usadas para manipular listas também podem ser usadas com cursores ArcPy.
Embora se possa usar a função embutida dir() para tentar retornar uma lista de atributos válidos para um objeto, vou evitar inspecionar os objetos dessa forma porque isso introduzirá confusão devido a todos os atributos que não estão relacionados à iteração. Em vez disso, vou confiar na função embutida isinstance() junto com as classes base abstratas (ABCs) embutidas para observar características de iteração.
>>