with
クリーンアップが必要なリソースの管理には、Python のステートメントを使用することをお勧めします。明示的なステートメントを使用する際の問題は、例外が発生したときにリソース リークを防ぐために、明示的なステートメントを呼び出すことをまったく忘れたり、ブロックにclose()
配置するのを忘れたりすることを心配する必要があることです。finally
このステートメントを使用するにはwith
、次のメソッドでクラスを作成します。
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
上記の例では、次を使用します
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)
次に、誰かがあなたのクラスを使用したい場合、次のようにします。
with Package() as package_obj:
# use package_obj
変数 package_obj は、タイプ Package のインスタンスになります (__enter__
メソッドによって返される値です)。その__exit__
メソッドは、例外が発生するかどうかに関係なく、自動的に呼び出されます。
このアプローチをさらに一歩進めることもできます。with
上記の例では、句を使用せずにコンストラクターを使用して Package をインスタンス化することができます。あなたはそれが起こることを望んでいません。__enter__
メソッドとメソッドを定義する PackageResource クラスを作成することで、これを修正できます__exit__
。次に、Package クラスが__enter__
メソッド内で厳密に定義され、返されます。with
そうすれば、呼び出し元はステートメントを使用せずに Package クラスをインスタンス化することはできません。
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()
これは次のように使用します。
with PackageResource() as package_obj:
# use package_obj