Sözlük anlamada SearchCursor'ta kullanılan imleç silinsin mi?


12

İmleçlerin silinmesini sağlamak için with ifadesini kullanarak açmak en iyiyse, şöyle:

with arcpy.da.UpdateCursor(fc,fields) as cursor:

Sonra, bir imleç aşağıdaki gibi bir anlamada yinelenebilir olarak kullanılırsa:

d = {k:v for (k,v) in arcpy.da.SearchCursor(fc,fields)}

Anlamada kullandıktan sonra imleci silmek gerekli mi?


1
Harika bir soru. Şema kilitlerini işlemeye mi çalışıyorsunuz? Benzer bir konuda bazı erken (çoğunlukla eski) yayınlar var, ancak yeni daimleçlerde kesin bir kaynak bulamıyorum : sgillies.net/2011/02/01/get-with-it.html ve help.arcgis.com/ tr / arcgisdesktop / 10.0 / help / index.html # //… . Özellikle, ilk bağlantının altındaki @JasonScheirer'in yorumlarına bakın.
Aaron

Yanıtlar:


13

Kesinlikle gerekli olup olmadığı sorulması yanlış bir sorudur. Soru, bunun iyi bir fikir olup olmadığıdır.

Programlamada kural olarak, garip şeyler yapmaktan kaçınmalı ve iş için en iyi aracı kullanmalısınız . Bir şeyin kaynakları serbest bırakmanın açık bir yolu varsa, sürümü serbest bırakın ve onunla yapın:

with arcpy.da.UpdateCursor(fc,fields) as cursor:
    d = {k: v for (k,v) in cursor}

Farkında olamayacağınız şey, withcümlenin aslında ek mantık başlatmasıdır. Bir withyan tümce, __enter__(blok girildiğinde __exit__çağrıldı ) ve (bloktan çıkıldığında çağrıldı) yöntemine sahip bir bağlam yöneticisi gerektirir . Özellikle, __exit__bir istisna oluşup oluşmadığından bağımsız olarak yöntem çağrılır ve programın hatayı bile hata ile serbest bırakmasını sağlar. Bu, kodunuza bir kaynağın ne zaman ve ne zaman serbest bırakıldığına dair açık belgeler verir ve bir kaynağın en kısa zamanda serbest bırakılmasını sağlar.

Aksine, sihirli bir şekilde hemen sizin için kapatmak için çalışma zamanına güvenemezsiniz. Bunun nedeni, kapanma şeklinin, nesnenin, hemen gerçekleşebilecek veya olmayabilecek yıkıcısını çağırmasıdır. Python, bir yıkıcının ne zaman çağrıldığına dair herhangi bir garanti vermez, sadece nesne çöp toplandığında olacaktır. (Bkz. Burada .) Şu anda, Python artık bir nesneye referans olmadığı anda gerçekleşecek şekilde uygulanmaktadır. Ancak bir nesneye referansları yanlışlıkla yaymak kolaydır ve Python'un çalışma zamanı değişebilir.

Ayrıca uzun süreli bakımı da göz önünde bulundurun. Orada kendisine hiçbir uzun vadeli referans şimdi, ama orada o kadar kodunu değiştirmek gerektiğinde neyi 6 ay içinde olur ise bir referans? Ya başka biri yaparsa? Değişikliği yapan kişi, orada bir withtane olmadığından bir bloğa geçmeyi düşünmeyebilir . Kaynaklarınızı temizlemeyi bir alışkanlık haline getirin ve bununla ilgili çok daha az sorun yaşarsınız.

Kodunuzu gerçekten çöp toplama uygulama ayrıntılarına bağlamak istiyor musunuz? İstisna yoluyla bir referansı yanlışlıkla yayıp yaymayacağınızı sürekli olarak düşünmek ister misiniz? Hayır. Bunun komut dosyası ArcMap'te çağrıldığında gerçekleşip gerçekleşmediğini düşünün. Kullanıcı sadece dosyayı serbest bırakmak için tüm işlemi kapatmak zorunda kalır. Bu yüzden kendinizi bu pozisyona sokmayın. Kaynağı açıkça bırakın. Bir satır kod kaydetmek, neden olabileceği sorunların riskine değmez. Bağlam yöneticileri Python'da kaynak edinme ve serbest bırakmanın standart mekanizmasıdır ve bunu çok iyi yaparlar.

Sonuç olarak, onu açıkça serbest bırakmamak kötü bir fikirdir.

Bu, elbette, kodun bir başkasını etkileme olasılığı olduğunu varsayar; örneğin, başka birinin çalıştırması veya sürdürmesi gereken bir komut dosyasına koymak veya ArcMap'i tamamen kapatmak zorunda kalırsanız çalışmanızı teslim etmeyi geciktirebilir. değişikliklerinizi kaydedemiyorum. Bir sorundan etkilenecek tek kişi sizseniz, elbette, iyi uygulamalar karşısında istediğiniz kadar uçun.


3

Hayır, cursorbir anlamada kullandıktan sonra bir silmeye gerek yoktur . A cursor, bir nesne olan bir sınıf örneğidir (python'daki her şey bir nesnedir). Her python oturumunda, oturumdaki namespacetüm nesnelere referanslar içeren bir anahtar vardır - bunu, anahtarların her nesneye referans olduğu ve değerler nesnelerin kendileri olduğu bir sözlük gibi düşünün. 'Referans sayısı' - bu nesneye başvuran anahtar sayısı - sıfıra düştüğünde , nesne kaldırılır ve bellek yeniden ayrılır . Bir cursoranlamada a kullandığınızda , ad alanında bu nesneye başvuru yoktur. Anlama tamamlandıktan sonra nesne silinecektir.

Ad alanında herhangi bir girdi yoktur ve bu nedenle hiçbir şeyi silmenize gerek yoktur. ESRI ayrıca burada örnek 2'deki sözdizimini gösterir .

Daha fazla açıklığa kavuşturmak için, şunları çalıştırırsanız:

>>> import arcpy
>>> f = r'C:\Workspace\study_area.shp'
>>> a = arcpy.da.SearchCursor(f, ['*'])

Dizinde bir .lock dosyası göreceksiniz (dosya gezgininizi kontrol edin). İmleç referansı , silinene kadar (ve dolayısıyla kilidi) devam aettirecektir . O zaman koştuğunuzda:cursora

>>> del(a)

Ad alanındaki giriş kaldırılır ve kilit açılır (.lock dosyası kaybolacaktır). Eğer koşarsan:

>>> t = [i for i in arcpy.da.SearchCursor(f, ['*'])]

Bir kilit dosyası görmezsiniz veya komut tamamlandığında kaybolur. Ad alanına giriş olmadan, cursorkalıcı değildir. tyeni oluşturduğunuz listeyi ifade eder, cursoroluşturmak için kullanılan listeyi değil .

Özetlemek gerekirse, yalnızca cursorsad alanında bir referansa sahip olduklarında (yani a, yukarıdaki örnekteki gibi bir değişkene atadığınızda) endişelenmeniz gerekir .


2
Bu son derece zayıf bir programlama uygulamasıdır. Bir şeyin kaynakları serbest bırakmanın açık bir yolu varsa, onu kullanırsınız .
jpmc26

@ jpmc26, "Son derece zayıf programlama uygulaması" hangi kısım? Genel olarak kavrayışlar? Ya da sadece yinelenebilir kavrayış içinde somutlaştırılmışsa? İkincisi için güçlü bir argümanın derhal kaynağı serbest bırakması olduğunu düşündüm.
Tom

@Tom Kaynakları açıkça yayınlamamak. Anlamalar harika araçlardır ve içlerinde normal tekrarlanabilirliklerin başlatılması tamamen normaldir. Burada kötü olan, imleç nesnelerinin dosya kilitleri edinmesi ve bunların açık bir sürümü olmamasıdır. Daha fazla ayrıntı için cevabıma bakın.
jpmc26

2

Söz konusu veri kümesi için özel bir kilit varsa, bir tablo veya özellik sınıfı için güncelleme ve ekleme imleçleri oluşturulamaz. Veri kümesindeki özel bir kilit nedeniyle UpdateCursor veya InsertCursor işlevleri başarısız olur. Bu işlevler başarıyla bir imleç oluşturuyorsa, veri kümesine özel bir kilit uygular, böylece iki komut dosyası aynı veri kümesine bir güncelleme oluşturamaz veya imleç ekleyemez.

Python'da kilit, imleç bırakılana kadar devam eder. Aksi takdirde, diğer tüm uygulamaların veya komut dosyalarının veri kümesine erişmesi gereksiz yere engellenebilir. Bir imleç aşağıdakilerden biri tarafından serbest bırakılabilir:

İmlecin başarılı bir şekilde tamamlanıp tamamlanmadığına bakılmaksızın kilitlerin serbest bırakılmasını garanti edecek bir with ifadesi içine imleci dahil etmek;

İmleç üzerindeki reset () çağrısı;

İmlecin tamamlanması;

Python'un del ifadesini ( ESRI) kullanarak imleci açıkça silme

Arcpy.da imleçleriyle kilitleme, orijinal arcpy imleçleriyle kilitleme ile hemen hemen aynıdır.

Kodunuzu test ettikten sonra ve gberard'ın işaret ettiği gibi, anlama sona erdikten sonra imlece hiçbir referans yoktur.
Ayrıca, kavrama sona erdikten sonra özellik sınıfı üzerinde kilit yoktur.


1
Ne siliniyor? Anlama sona erdikten sonra imleç nesnesine referans yoktur, bu yüzden teoride kapanmalıdır. ESRI uygulamasının beklediğiniz gibi davranıp davranmadığı başka bir sorudur ve belgelerin buna gerçekten cevap verdiğini düşünmüyorum.
mikewatt
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.