Python オブジェクトを適切にクリーンアップする
__del__() メソッドは、Python オブジェクトが破棄されたときにリソースをクリーンアップするためによく使用されます。ただし、__del__() の呼び出し中に「グローバル変数」の存在が保証されない Python のガベージ コレクション システムにより、__del__() に依存すると問題が発生する可能性があります。
適切なオブジェクトのクリーンアップを確保するには、次のことをお勧めします。 Python の with ステートメントを使用します。 with ステートメントはクラス インスタンスを引数として取り、例外に関係なく、クラスの __enter__() メソッドが開始時に呼び出され、その __exit__() メソッドが終了時に呼び出されることを保証します。
次のパッケージ クラスを考えてみましょう。
<code class="python">class Package: def __init__(self): self.files = [] # ... def __del__(self): for file in self.files: os.unlink(file)</code>
__del__() メソッドは、パッケージに属するすべてのファイルの削除を試みます。ただし、self.files への参照が欠落しているために失敗する可能性があります。これを解決するには、次のように __enter__() メソッドと __exit__() メソッドを定義します。
<code class="python">class Package: def __init__(self): self.files = [] def __enter__(self): return self # ... def __exit__(self, exc_type, exc_value, traceback): for file in self.files: os.unlink(file)</code>
ここで、with ステートメントで Package クラスを使用する場合、
<code class="python">with Package() as package_obj: # use package_obj</code>
__enter__() は次のようになります。 __exit__() は開始時に呼び出され、__exit__() は終了時に呼び出されることが保証されているため、例外が存在する場合でも適切なファイルのクリーンアップが保証されます。
with ステートメントを使用せずに Package クラスの誤って直接インスタンス化を防ぐには、 __enter__() メソッドと __exit__() メソッドを備えた PackageResource クラス:
<code class="python">class PackageResource: def __enter__(self): class Package: ... self.package_obj = Package() return self.package_obj def __exit__(self, exc_type, exc_value, traceback): self.package_obj.cleanup()</code>
このアプローチでは、Package クラスは with ステートメント内でのみインスタンス化できます:
<code class="python">with PackageResource() as package_obj: # use package_obj</code>
以上がPython でオブジェクトを適切にクリーンアップする方法: `__del__()` だけで十分ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。