72

私はPythonが初めてで、他の人のコードを読んでいます:

urllib.urlopen()の後にurllib.close()?を付ける必要があります。そうしないと、接続がリークしますよね?

4

5 に答える 5

105

closeメソッドは、あなたが考えているようにモジュール自体ではなく、の結果に対して呼び出す必要があります(あなたが言うように-これ存在しません)。urllib.urlopenurlliburllib.close

最善のアプローチ:x = urllib.urlopen(u)etcの代わりに、以下を使用します。

import contextlib

with contextlib.closing(urllib.urlopen(u)) as x:
   ...use x at will here...

withステートメントとコンテキストマネージャーはclosing、例外が存在する場合でも適切なクロージャーを保証します。

于 2009-10-05T22:22:17.130 に答える
14

@Peter が言うように、範囲外の開かれた URL はガベージ コレクションの対象になります。

urllib.pyただし、次のように定義されていることにも注意してください。

 def __del__(self):
        self.close()

これは、そのインスタンスの参照カウントが 0 に達すると、その__del__メソッドが呼び出され、したがってそのcloseメソッドも呼び出されることを意味します。参照カウントがゼロになる最も「通常の」方法は、単にインスタンスをスコープ外に出すことですが、明示的なdel x早期実行を厳密に止めるものは何もありません (ただし、直接呼び出すのではなく__del__、参照カウントを 1 つ減らすだけです)。 )。

リソースを明示的に閉じるのは確かに良いスタイルです (特に、アプリケーションが前述のリソースを使いすぎるリスクがある場合)。しかし、(循環?) 参照を維持するような面白いことをしなければ、Python自動的にクリーンアップします。もう必要のないインスタンスに。

于 2009-10-05T22:24:08.660 に答える
6

厳密に言えば、これは本当です。しかし実際には、一度 (if)urllib範囲外になると、接続は自動ガベージ コレクターによって閉じられます。

于 2009-10-05T22:07:57.997 に答える