私はPythonが初めてで、他の誰かのコードを読んでいます:
urllib.urlopen()
の後にurllib.close()
が続くべきですか?そうしないと、接続がリークしますよね?
close
メソッドは、urllib.urlopen
のresult、urllib
モジュール自体のnotで呼び出す必要がありますあなたが考えているように(あなたがurllib.close
に言及したように-これは存在しません)。
最善のアプローチ:x = urllib.urlopen(u)
などの代わりに、以下を使用します。
import contextlib
with contextlib.closing(urllib.urlopen(u)) as x:
...use x at will here...
with
ステートメントおよびclosing
コンテキストマネージャーは、例外が存在する場合でも適切に閉じられるようにします。
@Peterが言うように、スコープ外で開かれたURLはガベージコレクションの対象になります。
ただし、urllib.py
定義:
def __del__(self):
self.close()
これは、そのインスタンスの参照カウントがゼロに達すると、その __del__
メソッドが呼び出されるため、そのclose
メソッドも呼び出されます。参照カウントがゼロに達するための最も「通常の」方法は、単にインスタンスをスコープから外すことですが、明示的なdel x
早期(ただし、直接呼び出しません__del__
ただし、参照カウントを1だけ減らします。
リソースを明示的に閉じることは確かに良いスタイルです-特にアプリケーションが上記のリソースを使いすぎるリスクを実行する場合-しかしPythonwill不要なインスタンスへの(循環?)参照を維持するなど、おかしなことをしない場合は、自動的にクリーンアップします。
厳密に言えば、これは事実です。しかし、実際には、urllib
がスコープから外れると、自動ガベージコレクターによって接続が閉じられます。
基本的にdoIronPythonを使用する場合は、明示的に接続を閉じる必要があります。スコープ外への自動クローズは、ガベージコレクションに依存しています。ガベージコレクションが長時間実行されず、Windowsがソケットを使い果たしてしまうという状況に陥りました。私は高頻度でWebサーバーをポーリングしていました(つまり、IronPythonと接続で可能な限りの高さ、約7Hz)。 PerfMonで「確立された接続」(つまり、使用中のソケット)が上下することがわかりました。解決策は、urlopen
を呼び出すたびにgc.collect()
を呼び出すことでした。