Eu estava indeciso se escrevia um post no blog ou simplesmente abria uma discussão no espaço Python. Já faz um tempo desde que contribuí para o meu blog, então vou optar pela primeira opção.<\/EM><\/P>
<\/P>
A função ArcPy Data Access Walk (arcpy.da.Walk<\/SPAN>) é uma função realmente robusta, e eu dependo bastante dela. A função ArcPy Walk é um exemplo onde a Esri acertou na implementação em Python. Não posso dizer qual foi o objetivo de design deles, mas parece bastante claro que a intenção era criar uma versão geoespacialmente consciente da função os.walk <\/A>do Python. Os nomes são os mesmos, muitos dos parâmetros são os mesmos, os resultados são similares, etc.... Acho que emular essa funcionalidade nativa e antiga do Python no ArcPy foi uma vitória porque não reinventou uma roda perfeitamente boa, ou seja, usuários familiarizados com os.walk podem facilmente fazer a transição para usar arcpy.da.Walk.<\/P>
<\/P>
Por mais que eu goste da função ArcPy Walk, há alguns pequenos problemas que tenho com ela. O primeiro é um problema de documentação, ou melhor dizendo, falta de documentação. Um dos parâmetros da função Walk é datatype. A documentação tem uma tabela que lista todos os argumentos aceitáveis para datatype, mas não há documentação real sobre os próprios tipos de dados. Observando os nomes dos tipos de dados, parece que a maioria deles é óbvia, então talvez a Esri tenha decidido que não precisava documentá-los.<\/P>
<\/P>
Por mais descritivo que um nome possa parecer à primeira vista, a falta de documentação geralmente leva à ambiguidade e confusão. Por exemplo, o que está incluído em "FeatureClass"? Obviamente alguém assumiria que uma classe de feição em uma geodatabase está incluída, mas e quanto aos arquivos shape? Arquivos shape são classes de feição? No mundo Esri, a resposta geralmente é "Sim", mas nem sempre. O verdadeiro enigma é o tipo de dado "Geo", já que inclui arquivos shape mas não classes de feição em uma geodatabase. Classes de feição não são "geo?" Por mais importante que seja a documentação para bibliotecas/APIs, esse não é o principal motivo para escrever hoje.<\/P>
<\/P>
Um dos meus padrões favoritos com ArcPy Walk é chamar a função embutida do Python
next()<\/SPAN> uma vez para retornar uma lista de arquivos shape em uma pasta ou classes de feição em uma geodatabase ou classes de feição em um conjunto de feições.<\/P>
>>> workspace = #caminho para pasta ou geodatabase ou conjunto de feições
>>>
>>> _, _, filenames = next(arcpy.da.Walk(workspace, datatype="FeatureClass"))
>>> filenames
[u'canadwshed_p.shp', u'plots.shp']
>>>
>>> #ou iterando sobre classes de feição ou arquivos shape
>>> for file in next(arcpy.da.Walk(workspace, datatype="FeatureClass"))[2]:
... print file
canadwshed_p.shp
plots.shp
>>>
<\/code><\/pre>
<\/P>
No primeiro exemplo, crio um objeto Workspace Walker descartável que não preciso me preocupar em manter ou desmontar. No segundo exemplo, chamar next() no loop for me permite eliminar um loop extra quando estou interessado apenas em um nível de dados geoespaciais.<\/P>
<\/P>
Como acontece com a maioria das coisas na vida, não existe apenas uma maneira de listar classes de feição em uma geodatabase ou arquivos shape em uma pasta. De fato, a função ArcPy Walk é o novato sendo introduzido no ArcGIS 10.1 SP1. Antes do ArcPy Walk, um usuário poderia usar uma das muitas funções de listagem do ArcPy (ListDatasets, ListFeatureClasses, ListFiles, ListRasters, ListTables, e ListWorkspaces) ou a função ArcPy Describe . Eu tendo a preferir ArcPy Walk sobre as outras por sua facilidade de uso e similaridade com funcionalidades embutidas do Python.<\/P>
<\/P>
O principal motivo deste post no blog é compartilhar uma área onde a função ArcPy Walk tropeça, ou seja, fontes de dados em memória. Enquanto os métodos antigos para listar fontes de dados funcionam com workspaces em memória, esse não é o caso do ArcPy Walk.<\/P>
>>> arcpy.CreateFeatureclass_management('in_memory', 'test_fc')
<Result 'in_memory\\test_fc'>
>>> arcpy.CreateTable_management('in_memory', 'test_tbl')
<Result 'in_memory\\test_tbl'>
>>> arcpy.CreateRasterDataset_management('in_memory','test_rd')
<Result 'in_memory\\test_rd'>
>>>
>>> #usando ArcPy Walk
>>> next(arcpy.da.Walk('in_memory'))[2]
[]
>>>
>>> #usando funções de listagem do ArcPy
>>> arcpy.env.workspace = 'in_memory'
>>> arcpy.ListFeatureClasses()
[u'test_fc']
>>> arcpy.ListTables()
[u'test_tbl']
>>> arcpy.ListRasters()
[u'test_rd']
>>> arcpy.ListDatasets()
[u'test_rd']
>>>
>>> #usando função Describe do ArcPy
>>> [child.name for child in arcpy.Describe('in_memory').children]
[u'test_tbl', u'test_fc', u'test_rd']
>>>
<\/code><\/pre>
<\/P>
Não suportar workspaces em memória não é muito mais do que um tropeço, mas ainda assim é um tropeço. Afinal, a documentação diz que o primeiro parâmetro é o "workspace de nível superior", mas nenhuma menção é feita ao fato de workspaces em memória não serem suportados. Felizmente para os usuários, existem pelo menos duas outras maneiras de listar fontes de dados em memória.<\/P>
<\/P>
ATUALIZAÇÃO 06/2017:<\/STRONG><\/P>
<\/P>
Desde que escrevi este post no blog há quase 18 meses (Eu sei "o tempo voa", mas ainda assim, já se passaram 18 meses?), descobri que o problema com ArcPy Walk e workspaces em memória é mais complexo do que eu pensava originalmente. Deixe-me demonstrar:<\/P>
>>> arcpy.CreateFeatureclass_management('in_memory', 'test_fc')
<Result 'in_memory\\test_fc'>
>>> arcpy.CreateTable_management('in_memory', 'test_tbl')
<Result 'in_memory\\test_tbl'>
>>> arcpy.CreateRasterDataset_management('in_memory','test_rd')
<Result 'in_memory\\test_rd'>
>>>
>>> # usando ArcPy Walk com "GPInMemoryWorkspace" ao invés do comum "in_memory"
>>> next(arcpy.da.Walk('GPInMemoryWorkspace'))[2]
[u'test_tbl', u'test_fc', u'test_rd']
>>> <\/code><\/pre>
<\/P>
Então, acontece que o ArcPy Walk funciona muito bem com workspaces em memória quando ele realmente sabe que você está apontando para um workspace em memória. A parte realmente frustrante disso, e até um pouco lamentável, é que isso se resume simplesmente à semântica e a Esri ainda não conseguiu corrigir isso. Funcionalmente, o ArcPy Walk já funciona com workspaces em memória, só que a função não sabe que todo mundo e todas as outras ferramentas se referem a esses espaços como "in_memory" ao invés de "GPInMemoryWorkspace".<\/P>