Daha çox

İstifadəçi İptal düyməsini tıkladıqda Python Toolbox alətini döngəni pozmağa və təmizləmə etməyə məcbur edirsiniz?


Bir döngədə ağır vəzifələri yerinə yetirən bir Python aləti yazıram. İstifadəçi "Bağla" düyməsini basdıqda, döngəni pozmaq, bir az təmizləmə aparmaq və sonra bitirmək istəyirəm.

Ondan sayılan bu nümunə aləti nəzərdən keçirin:

import arcpy import time class Tool (object): def __init __ (self): self.label = "Cancel Test" self.description = "Ləğv etmə funksiyasının necə işlədiyini sınayır." self.canRunInBackground = Yanlış def icra (öz, parametrlər, mesajlar): i aralığında (10, -1, -1): arcpy.AddMessage (i) time.sleep (1) arcpy.AddMessage ("Bizdə lift var. sön! ") qayıt

İcra başlanğıcında "Bağla" düyməsini basdığımda döngə əyləc etməz və ya hər hansı bir təmizləmə aparmağa imkan vermir. Bunun əvəzinə sonuna qədər dönər və mesajı əlavə edər"Uçuşumuz var!"bunu çıxarmazdan əvvəl:

Tamamlanmış skript CancelTest… İstifadəçi tərəfindən ləğv edilmiş funksiya (CancelTest) ləğv edildi. [TIME] uğursuz oldu (Keçən Zaman: 10,01 saniyə)

ArcGIS Pro (Python 3.4 istifadə edən) üçün bunu orada necə edə biləcəyinizi izah edən sənədlər tapdım.ləğv edildi:

idxal arcpy idxal vaxtı #Avtomatik olaraq ləğv etmədiyinə əmin olun. arcpy.env.autoCancelling = Yanlış sinif aləti (obyekt): def __init __ (özünü): self.label = "Testi ləğv et" self.description = "Ləğv funksiyasının necə işlədiyini sınayır." self.canRunInBackground = Yanlış def icra (özünü, parametrlər, mesajlar): i aralığında (10, -1, -1): arcpy.AddMessage (i) time.sleep (1) #İstifadəçinin "Bağla" düyməsini tıkladığını yoxlayın əgər arcpy.env.isCancelled: arcpy.AddMessage ("Launch ləğv edildi!") qayıt arcpy.AddMessage ("Bizdə qalxma var!") qayıt

Ancaq bunu ArcCatalog 10.3 -dən işlədəndə (yəni ArcGIS Pro istifadə etmədən) mənə aşağıdakı xətanı verir:

İzləmə (son son zəng): "H:  Mina Dokument  DGD  Python  CancelTest.py" faylı 19, arcpy.env.isCancelled əgər icra edildikdə: AttributeError: 'GPEnvironment' obyektinin 'isCancelled' atributu yoxdur

Python 2.7 istifadə edərək adi bir Python alət qutusunda ArcGIS Pro -da mövcud olan davranışı təqlid etmək üçün hər hansı bir şey varmı?


Fərid Çerin cavabı qismən doğrudur.

Proqramı bir Python skriptində ləğv edilən bir hadisəni 'tutmaq' üçün istifadə edə bilərsiniz və lazım olan hər hansı bir təmizliyi də edə bilərsiniz.cəhd edin ... istisna olmaqlabənd.

Məsələn, bir python alət qutusu:

idxal arcpy idxal vaxt sinif Toolbox (obyekt): def __init __ (özünü): self.label = "Toolbox" self.alias = "" self.tools = [Alət] sinif Aləti (obyekt): def __init __ (özünü): özünü. label = "Tool" self.description = "" self.canRunInBackground = Yanlış def icra (öz, parametrlər, mesajlar): some_stuff = [] # sonradan təmizlənəcək bir dəyişən max = 1000 arcpy.SetProgressor ('addım', 'ArcPy Testi) script ləğv et ', 0, max, 1) # For loopunda olmaq məcburiyyətində deyilsən, amma bu, i üçün nümunə göstərmək üçün ən asan # yoldur (max): cəhd edin: # yalnız SetProgressorPosition qoy maddə # əks halda arcpy.SetProgressorPosition () istifadəçisini ləğv edən # olmayan digər səhvləri tuta bilərsiniz: arcpy.AddWarning ('İstifadəçi i = {0} tarixində ləğv edildi. yuxu (0.1) some_stuff.append (i) arcpy.AddMessage ('İstifadəçi ləğv etmədi' ') del some_stuff

Bu istifadəçiyə aləti işə salmağa imkan verir:

Və sonra zərif bir şəkildə işlənən ləğv edin (və hələ də uğursuz bir qaçış sayılır):

redaktə edin: Bu 10.3 və ya ArcGIS Pro ilə işləmir.

Ləğvləri tutmaq üçün (ArcGIS Pro -da sınaqdan keçirilmişdir) yaxşı dostumuzu geri gətiririkarcgisscripting. Bu, irəliləyicidən ləğv etməyi tutmağa bənzəyir, lakin bütün icra funksiyasının və ya ən azından əksəriyyətinin daxilində olması lazımdır.cəhd edin:

idxal arcpy idxal arcgisscripting idxal vaxt sinif Toolbox (obyekt): def __init __ (özünü): self.label = "Toolbox" self.alias = "" self.tools = [Tool] sinif Alət (obyekt): def __init __ (özünü): self.label = "Alət" self.description = "" self.canRunInBackground = Yanlış def icra (özünü, parametrlər, mesajlar): cəhd edin: some_stuff = [] max = 1000 arcpy.SetProgressor ('addım', 'ArcPy skriptini yoxlamaq İ, aralığında (max): 0, max, 1) } '. format (i)) del_duff arcpy.AddMessage (' İstifadəçi ləğv etmədi '') del some_stuff


Mesajınız aydındır:

AttributeError: 'GPEnvironment' obyektinin 'isCancelled' atributu yoxdur

Faktiki olaraqarcpy.env.autoCancellingarcpy.env.is ləğv edildiArcgis Pro 1.1 -ə əlavə olunur (ArcGIS 10.4 üçün planlaşdırılır)

Bundan əlavə, Arcgis 10.3 istifadə edirsinizsə, bu xüsusiyyətlər mövcud deyil.


Düşündüyüm ən yaxın yol Arcpy -də Progressor -un istifadəsidir. Proqressor istifadə edərək, istifadəçi ləğv düyməsini basdıqdan sonra döngə pozulur və icra dayandırılır. Ancaq heç bir təmizlik edə bilməzsiniz! Budur nümunə kod:

def execute (öz -özünə, parametrlər, mesajlar): idxal vaxtı n = 10 p = 1 arcpy.SetProgressor ("addım", "Addım irəliləyicisi: 0 -dan {0}" -ə qədər format. (n), 0, n, p) loopTime = .3 i üçün (n): əgər (i % p) == 0: ## xüsusi kodunuzu bura qoyun ## istifadəçi ləğv edərsə döngəni pozar. və alət icrası arcpy.SetProgressorLabel ("İterasiya: {0}". format (i)) arcpy.SetProgressorPosition (i) time.sleep (loopTime) arcpy.AddMessage ("Əgər döngə olarsa təmizləmə üçün bura gəlməyəcəksiniz. vaxtından əvvəl bitirir ") arcpy.SetProgressorLabel (" İterasiya bitdi: {0} ". format (i + 1)) arcpy.SetProgressorPosition (i + 1) qaytar

Yeniləmə (şərhdəki suallara cavab vermək üçün):

Niyə bir inkişaf etdirici istifadə etmək, gözəl görünən bir irəliləyiş çubuğu əlavə etməkdən başqa, proqramın davranışını dəyişir?

Proqressor bir növ çox işlənmiş bir emaldır. mütərəqqi hər dəfə irəli addım atanda GUI (ayrı bir mövzu) yenilənməlidir. Bir mütərəqqi istifadə edərkən kodunuzu başqa bir sətirdə işlədirsiniz. Bununla birlikdə, eyni anda birdən çox mövzu işlədə biləcəyiniz Fon geo emalına bənzəmir.

İstifadəçi "İptal et" düyməsini basdıqda bir mütərəqqi istifadə etmək, ArcGIS kodunu əyləc etməyə vadar edirmi?

Bəli, qırılma, irəliləyiş çubuğunuzu yenilədiyiniz döngədə baş verdiyini unutmayın (məsələn, yuxarıdakı nümunə kimi)

harada qırılır? Düymə basıldığında baş verən hər hansı bir xəttdən dərhal sonra?

Qırılma, istifadəçinin ləğv düyməsini basdığı ​​hər iki irəliləyiş addımı arasında baş verir. Yuxarıdakı kod nümunəsində onun:

if (i % p) == 0: ## xüsusi kodunuzu bura qoyun ## istifadəçi ləğv edərsə döngəni pozar. və alət icrası arcpy.SetProgressorLabel ("İterasiya: {0}". format (i)) sona çatır

İstifadəçi basınsaləğv et, Xüsusi kodunuz çatana qədər icra ediləcəkarcpy.SetProgressorLabel ("Yineleme: {0}". format (i)). Gp alətinin ləğv hadisəsi barədə xəbərdarlıq alacağı yerdir (məsələn, ayrı sətir ipini öldür)


Videoya baxın: Scikit Learn Machine Learning SVM Tutorial with Python p. 2 - Example (Oktyabr 2021).