사전 이해 내에서 SearchCursor에 사용 된 커서를 삭제 하시겠습니까?


12

with 문을 사용하여 커서를 열어서 삭제되도록하려면 다음과 같이하십시오.

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

그런 다음 커서가 다음과 같이 이해에서 반복 가능으로 사용되는 경우 :

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

이해에 커서를 사용한 후 커서를 삭제해야합니까?


1
좋은 질문입니다. 스키마 잠금을 처리하려고합니까? 새 da커서에서 sgillies.net/2011/02/01/get-with-it.htmlhelp.arcgis.com/ 이라는 결정적인 소스를 찾을 수는 없지만 비슷한 주제에 대한 초기 (주로 오래된) 게시물이 있습니다 . 엔 / arcgisdesktop / 10.0 / 도움말 / index.html을 # // ... . 특히 첫 번째 링크의 맨 아래에있는 @JasonScheirer의 의견을보십시오.
Aaron

답변:


13

꼭 필요한지 여부는 잘못된 질문입니다. 문제는 그것이 좋은 아이디어인지의 여부입니다.

프로그래밍의 원칙에 따라 이상한 일을 피하고 작업에 가장 적합한 도구를 사용해야합니다 . 어떤 것에서 명시 적으로 자원을 방출하는 방법이 있다면, 그 릴리스를 명시 적으로 만들어서 수행하십시오.

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

당신이 알지 못하는 것은이 with절이 실제로 추가 논리를 호출 한다는 것입니다. with절은 가져야 콘텍스트 관리자 필요 __enter__(블록이 입력 될 때 호출)하고 __exit__(블록이 종료 될 때 호출) 방법. 특히, __exit__메소드는 예외 발생 여부에 관계없이 호출되어 프로그램이 오류가 발생하더라도 항상 자원을 해제하도록합니다. 이를 통해 리소스를 획득 한 시점과 해제 된 시점에 대한 코드를 명시 적으로 문서화 할 수 있으며 가능한 빨리 리소스를 해제 할 수 있습니다.

반대로 실제로는 런타임에 의존하여 마술처럼 즉시 닫을 수는 없습니다. 닫히는 방식은 객체의 소멸자를 호출하는 것이므로 즉시 발생하거나 발생하지 않을 수 있기 때문입니다. 파이썬은 소멸자가 호출되는 시점을 보장하지 않으며 결국 객체가 가비지 수집 될 때만 보장합니다. ( 여기 참조 ) 현재 파이썬은 더 이상 객체에 대한 참조가없는 즉시 발생하도록 구현되었습니다. 그러나 실수로 객체에 대한 참조를 전파하기 쉽고 파이썬의 런타임이 변경 될 수 있습니다.

장기 유지 보수도 고려하십시오. 지금은 장기 참조가 없지만 참조 있도록 코드를 수정해야 할 때 6 개월 안에 어떤 일이 발생 합니까? 다른 사람이하면 어떻게 되나요? 변경을 한 사람은 with블록이 없기 때문에 블록 으로 전환하지 않을 수도 있습니다. 리소스 정리를 습관화 하면 문제가 훨씬 줄어 듭니다.

가비지 수집의 구현 세부 정보에 코드를 연결 하시겠습니까? 예외를 통해 실수로 참조를 전파 할 수 있는지에 대해 끊임없이 생각하고 싶습니까? 아뇨 ArcMap에서 스크립트가 호출 될 때 이런 일이 발생했다고 상상해보십시오. 사용자는 파일을 해제하기 위해 전체 프로세스를 닫아야합니다. 따라서 그 자리에 자신을 두지 마십시오. 자원을 명시 적으로 해제하십시오. 한 줄의 코드를 저장하면 문제가 발생할 위험이 없습니다. 컨텍스트 관리자는 파이썬에서 리소스를 수집하고 해제하기위한 표준 메커니즘이며 매우 잘 수행됩니다.

결론은 명시 적으로 공개하지 않는 것은 나쁜 생각입니다.

물론 이것은 코드가 다른 사람에게 영향을 줄 가능성이 있다고 가정합니다. 다른 사람이 실행하거나 유지해야 할 스크립트에 넣거나 ArcMap을 완전히 닫아야하는 경우 작업 수행을 지연시킬 수 있습니다. 변경 사항을 저장할 수 없습니다. 당신이 문제에 의해 영향을받는 유일한 사람이라면, 항상 당신이 원하는 모든 좋은 관행에 직면하십시오.


3

아니요, cursor이해에 사용한 후에 는 삭제할 필요가 없습니다 . A cursor는 클래스의 인스턴스이며 객체입니다 (파이썬의 모든 것은 객체입니다). 모든 파이썬 세션에는 세션의 namespace모든 객체에 대한 참조가 포함되어 있습니다. 키는 각 객체에 대한 참조이며 값은 객체 자체 인 사전과 같습니다. 해당 객체를 참조하는 키의 수인 '참조 횟수'가 0으로 떨어지면 객체가 제거되고 메모리가 다시 할당 됩니다. cursor이해에 a 를 사용 하면 네임 스페이스에 해당 객체에 대한 참조가 없습니다. 이해가 끝나면 객체가 삭제됩니다.

네임 스페이스에는 항목이 없으므로 아무것도 삭제할 필요가 없습니다. ESRI는 또한 예제 2 의이 구문을 보여줍니다 .

더 명확하게 설명하면 다음을 실행하십시오.

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

디렉토리에 .lock 파일이 나타납니다 (파일 탐색기 확인). 커서에 대한 참조는입니다 a. 그러면 삭제 cursor될 때까지 잠금이 유지 a됩니다. 따라서 다음을 실행할 때 :

>>> del(a)

네임 스페이스의 항목이 제거되고 잠금이 해제됩니다 (.lock 파일이 사라짐). 당신이 실행하는 경우 :

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

잠금 파일이 표시되지 않거나 명령이 완료되면 사라집니다. 네임 스페이스에 항목 cursor이 없으면 영구적이지 않습니다. t는 방금 생성 한 목록이 아니라 방금 생성 한 목록을 나타냅니다 cursor.

요약 cursors하면 네임 스페이스에 참조가있는 경우 (예 : a위의 예 와 같이 변수에 할당 한 경우) 삭제하는 것만 걱정 하면됩니다 .


2
이것은 매우 열악한 프로그래밍 실습입니다. 무언가 자원을 명시 적으로 방출하는 방법이 있다면 그것을 사용하십시오 .
jpmc26

@ jpmc26, "매우 가난한 프로그래밍 연습"은 어느 것입니까? 이해력은? 아니면 iterable이 이해 내에서 인스턴스화 된 경우에만? 후자에 대한 강력한 주장 중 하나는 즉시 리소스를 해제한다는 것입니다.
Tom

@Tom 리소스를 명시 적으로 공개하지 않습니다. 이해력은 환상적인 도구이며, 그 안에 일반 이터 러블을 인스턴스화하는 것은 완전히 정상입니다. 여기서 나쁜 점은 커서 객체가 파일 잠금을 획득하고 명시 적으로 릴리스되지 않았다는 것입니다. 자세한 내용은 내 답변을 참조하십시오.
jpmc26

2

해당 데이터 세트에 대한 독점 잠금이 존재하는 경우 테이블 또는 기능 클래스에 대해 업데이트 및 삽입 커서를 작성할 수 없습니다. 데이터 세트의 독점 잠금으로 인해 UpdateCursor 또는 InsertCursor 함수가 실패합니다. 이러한 함수가 커서를 성공적으로 만들면 두 스크립트가 동일한 데이터 집합에서 업데이트를 만들거나 커서를 삽입 할 수 없도록 데이터 집합에 독점 잠금을 적용합니다.

Python에서는 커서가 놓일 때까지 잠금이 유지됩니다. 그렇지 않으면 다른 모든 응용 프로그램이나 스크립트가 불필요하게 데이터 세트에 액세스하지 못할 수 있습니다. 커서는 다음 중 하나에 의해 해제 될 수 있습니다.

with 문 안에 커서를 포함하면 커서가 성공적으로 완료되었는지 여부에 관계없이 잠금 해제가 보장됩니다.

커서에서 reset () 호출;

커서의 완성.

Python의 del 문을 사용하여 커서를 명시 적으로 삭제 -ESRI

arcpy.da 커서로 잠그는 것은 원래의 arcpy 커서로 잠그는 것과 거의 같습니다.

코드를 테스트 한 후 gberard가 지적했듯이 이해가 끝난 후에는 커서에 대한 참조가 없습니다.
또한 이해가 끝난 후 피쳐 클래스에는 잠금이 없습니다.


1
무엇을 삭제 하시겠습니까? 이해가 끝나면 커서 객체에 대한 참조가 없으므로 이론 상으로는 커서 객체가 닫힙니다. ESRI의 구현이 예상대로 작동하는지 여부는 또 다른 질문이며 문서가 실제로 그 대답에 있다고 생각하지 않습니다.
mikewatt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.