回答:
絶対に必要かどうかは、尋ねるのが間違っている質問です。問題は、それが良いアイデアかどうかです。
プログラミングのルールとして、あなたは奇妙なことをすることを避け、仕事に最適なツールを使用する必要があります。何かにリソースを解放する明示的な方法がある場合は、リリースを明示的に行い、それで完了します。
with arcpy.da.UpdateCursor(fc,fields) as cursor:
d = {k: v for (k,v) in cursor}
気づかないかもしれませんが、このwith
句は実際に追加のロジックを呼び出します。with
句は有していなければならないコンテキストマネージャ、必要__enter__
(ブロックが入力されたときに呼び出さ)と__exit__
(ブロックが終了されたときに呼び出される)方法を。特に、__exit__
例外が発生したかどうかに関係なくメソッドが呼び出されるため、プログラムはエラーが発生しても常にリソースを解放します。これにより、リソースがいつ取得され、いつ解放されるかをコードに明示的に示すことができ、リソースをできるだけ早く解放できるようになります。
対照的に、実際にランタイムに依存して魔法のようにすぐに閉じることはできません。これは、オブジェクトを閉じる方法がオブジェクトのデストラクタを呼び出すことであるためです。Pythonは、デストラクタがいつ呼び出されるかについては保証しませんが、オブジェクトがガベージコレクションされるときに最終的に保証されるだけです。(こちらを参照してください。)現在、Pythonは実装されているため、オブジェクトへの参照がなくなるとすぐにPythonが実行されます。しかし、誤ってオブジェクトへの参照を伝播するのは簡単であり、Pythonのランタイムが変更される可能性があります。
長期的なメンテナンスも考慮してください。現在、長期的な参照はありませんが、参照があるようにコードを変更する必要がある場合、6か月で何が起こりますか?他の誰かがそれをした場合はどうなりますか?変更を行う人は、with
ブロックがまだ存在しないため、ブロックに切り替えるとは思わないかもしれません。リソースをクリーンアップすることを習慣にすると、問題をはるかに少なくすることができます。
ガベージコレクションの実装の詳細にコードを本当に関連付けたいですか?例外を介して誤って参照を伝播している可能性があるかどうかを常に考えなければなりませんか?いいえ、そうではありません。スクリプトがArcMapで呼び出されたときにそれが起こった場合を想像してください。ユーザーは、ファイルを解放するためだけにプロセス全体を閉じることを強制されます。ですから、そのような立場に置かないでください。リソースを明示的に解放します。1行のコードを保存しても、それが引き起こす問題のリスクに見合う価値はありません。コンテキストマネージャーは、Pythonでリソースを取得および解放するための標準メカニズムであり、非常にうまく機能します。
結論としては、明示的にリリースしないことは悪い考えです。
もちろん、これは、コードが他の誰かに影響を与える可能性があることを前提としています。他の誰かが実行または保守する必要があるスクリプトにコードを入れるなど、変更を保存できません。あなたが問題の影響を受けるのはあなただけであるならば、どうしても、あなたが望むすべての良い慣行に直面して飛びましょう。
いいえ、cursor
理解してから使用した後に削除する必要はありません。A cursor
はオブジェクトのクラスのインスタンスです(Pythonのすべてはオブジェクトです)。すべてのpythonセッションには、セッションnamespace
内のすべてのオブジェクトへの参照を含むがあります。キーは各オブジェクトへの参照であり、値はオブジェクトそのものである辞書のように考えてください。「参照カウント」-そのオブジェクトを参照するキーの数-がゼロになると、オブジェクトが削除され、メモリが再割り当てされます。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
、上記の例のように変数に変数を割り当てた場合)に削除することだけを心配する必要があります。
そのデータセットに排他ロックが存在する場合、テーブルまたはフィーチャクラスに対して更新および挿入カーソルを作成できません。データセットの排他ロックのため、UpdateCursorまたはInsertCursor関数は失敗します。これらの関数がカーソルを正常に作成すると、データセットに排他ロックを適用し、2つのスクリプトが同じデータセットに更新カーソルまたは挿入カーソルを作成できないようにします。
Pythonでは、カーソルが解放されるまでロックが持続します。そうしないと、他のすべてのアプリケーションまたはスクリプトが不必要にデータセットにアクセスできなくなる可能性があります。カーソルは、次のいずれかによって解放できます。
withステートメント内にカーソルを含めると、カーソルが正常に完了したかどうかに関係なく、ロックの解放が保証されます。
カーソルでreset()を呼び出します。
カーソルの完了。
Pythonのdelステートメントを使用してカーソルを明示的に削除する-ESRI
arcpy.daカーソルを使用したロックは、元のarcpyカーソルを使用したロックとほとんど同じです。
コードをテストした後、gberardが指摘したように、理解の終了後はカーソルへの参照はありません。
また、理解の終了後、フィーチャクラスにロックはありません。
da
カーソルに関する明確なソースを見つけることができませんが、同様のトピックに関するいくつかの初期の(ほとんど時代遅れの)投稿があります:sgillies.net/2011/02/01/get-with-it.htmlおよびhelp.arcgis.com/ ja / arcgisdesktop / 10.0 / help / index.html#//…。特に、最初のリンクの下部にある@JasonScheirerのコメントを見てください。