<\/HEAD>
Dit is het eerste deel in een serie met meerdere delen over ArcPy cursors; met name het werken met ArcPy cursors als iterabele objecten in Python. Het eerste deel in de serie<\/STRONG> behandelt enkele belangrijke componenten van iteratie in Python. Het tweede deel in de serie<\/A> gaat over het itereren en doorlopen van ArcPy Data Access cursors. Het derde deel in de serie<\/A> behandelt het gebruik van verschillende ingebouwde Python- en itertools-functies met ArcPy Data Access cursors. Het vierde deel in de serie zal gaan over het gebruik van generators of generator-expressies om selectie- of filterlogica te scheiden voor hergebruik van code. Vijfde of volgende delen zijn op dit moment onbekend.<\/EM><\/P><\/P>
Deze en de volgende reeks blogposts richten zich op
ArcPy Data Access<\/A> cursors in de context van iteratie, vandaar de titel van de serie. Nu lijkt het misschien vreemd om te praten over iterabele cursors aangezien een cursor eigenlijk waardeloos is zonder iteratie, maar mijn ervaring met scripten met ArcPy cursors en het beantwoorden van vragen op GeoNet heeft mij gemotiveerd om enkele Pythonische manieren te delen om over cursors na te denken en ermee te werken.<\/P><\/P>
Bij het praten over iteratie in Python zijn er talrijke termen en uitdrukkingen die relevant kunnen zijn voor een discussie. Vijf termen die ik vooral belangrijk vind, en relevant voor deze serie blogposts, zijn:<\/P>
Woordenlijst<\/A><\/SPAN><\/P>generator<\/STRONG><\/P>Een functie die een iterator teruggeeft. Het lijkt op een normale functie behalve dat het
yield<\/SPAN> <\/A> instructies bevat om een reeks waarden te produceren die bruikbaar zijn in een for-lus of die één voor één kunnen worden opgehaald met de next()<\/A><\/SPAN> functie. Elke yield<\/SPAN> <\/A> pauzeert tijdelijk de verwerking, waarbij de locatie en uitvoeringsstatus (inclusief lokale variabelen en lopende try-instructies) worden onthouden. Wanneer de generator hervat, pakt hij op waar hij was gebleven (in tegenstelling tot functies die bij elke aanroep opnieuw beginnen).<\/P><\/P>generator-expressie<\/STRONG><\/P>Een expressie die een iterator teruggeeft. Het lijkt op een normale expressie gevolgd door een for<\/SPAN> <\/A> expressie die een lusvariabele, bereik en een optionele if<\/A><\/SPAN> expressie definieert. De gecombineerde expressie genereert waarden voor een omliggende functie:<\/P><SPAN class="operator token">>><\/SPAN><SPAN class="operator token">><\/SPAN> sum<SPAN class="punctuation token">(<\/SPAN>i<SPAN class="operator token">*< \/span>i <span class=\"keyword token\">for< \/span> i <span class=\"keyword token\">in< \/span> range<SPAN class=\"punctuation token\">(< \/span><span class=\"number token\">10< \/span><span class=\"punctuation token\">)< \/span><span class=\"punctuation token\">)< \/span> <span class=\"comment token\"># som van kwadraten 0, 1, 4, ... 81< \/span>
<span class=\"number token\">285< \/span>
<span class=\"line-numbers-rows\"><span><<EMOJI_0>>< \/span><span><<EMOJI_1>>< \/span></span>
< \/P>
iterable< \/STRONG>
Een object dat in staat is zijn leden één voor één terug te geven. Voorbeelden van iterables zijn alle sequentietypen (zoals
list< \/A>, str< \/A>, en tuple< \/A>) en sommige niet-sequentietypen zoals dict< \/A> en file< \/A> < \/SPAN>en objecten van elke klasse die u definieert met een iter() functie of gebruik het in een for lus. Pogingen hiermee met een iterator zullen gewoon hetzelfde uitgeputte iterator-object retourneren dat in de vorige iteratieronde werd gebruikt, waardoor het lijkt alsof het een lege container is.
sequence
Een iterable die efficiënte elementtoegang ondersteunt met behulp van gehele indices via de __getitem__() speciale methode en een len() methode definieert die de lengte van de sequence retourneert. Sommige ingebouwde sequentietypen zijn list, str, tuple, en unicode. Merk op dat dict ook __getitem__() en __len__() ondersteunt, maar wordt beschouwd als een mapping in plaats van een sequence omdat de opzoekingen willekeurige immutable sleutels gebruiken in plaats van gehele getallen.
Vergeleken met de oude woordenlijst van ArcGIS Resources, nu hernoemd tot GIS Dictionary en ondergebracht bij Esri Support, is de Python Glossary tamelijk uitgebreid. Dat gezegd hebbende, is de Python Glossary ook een van die woordenlijsten die logisch is voor mensen die het antwoord al kennen, maar het kan wat moeilijker zijn voor mensen die nieuw zijn in de taal.
Uit het bovenstaande fragment van de woordenlijst kan men afleiden dat een paar speciale/magische/dunder-methoden erg belangrijk zijn voor iteratie: __iter__(), __getitem__(), en next() (of __next__() als men werkt in Python 3.x). Er zijn ook een paar belangrijke ingebouwde functies die met deze methoden interageren: iter() en next(). En last but not least, de for lus en de yield instructie. Er zijn meer methoden, functies, instructies en controle structuren betrokken bij iteratie, maar de eerder genoemde zijn centraal in elke discussie. Voor lezers die geïnteresseerd zijn om meer te leren over iterators, generators, sequences, enz...; er zijn talloze primers en tutorials geschreven die slechts een snelle Google-zoekopdracht verwijderd zijn.
Lijsten zijn zo gebruikelijk in Python, en nieuwkomers in de taal krijgen er zo vroeg mee te maken, dat ik Python lijstvoorbeelden zal gebruiken voor context naast de ArcPy Data Access search cursor voorbeelden. De Python Glossary stelt dat een lijst "een ingebouwde Python sequence is," en een sequence is "een iterable die efficiënte elementtoegang ondersteunt met behulp van gehele indices...." De ArcPy Data Access SearchCursor documentatie stelt dat de search cursor "een iterator van tuples retourneert." Aangezien iterators ook iterable zijn, krijgt men het gevoel dat ingebouwde functies en expressies die vaak worden gebruikt voor het manipuleren van lijsten ook kunnen worden gebruikt met ArcPy cursors.
Hoewel men de ingebouwde dir() functie kan gebruiken om te proberen een lijst van geldige attributen voor een object terug te geven, ga ik ervan afzien om de objecten op die manier te inspecteren omdat dit rommel zal introduceren door alle attributen die niet gerelateerd zijn aan iteratie. In plaats daarvan zal ik vertrouwen op de ingebouwde isinstance() functie samen met ingebouwde abstract base classes (ABCs) om naar iteratie-eigenschappen te kijken.
>>