0

sqliteデータベース接続やファイルなどのリソースをラップするクラスがあるwith場合、オブジェクトがスコープ外になったときや gcollected になったときにステートメントを使用してリソースを閉じる方法はありますか?

私が言いたいことを明確にするために、これを避けたい:

class x:
    def __init__(self):
        # open resource

    def close(self): # or __del__, even worst
        # close resource

ただし、次のようにリソースが常に解放されるようにします。

with open('foo') as f:
    # use resource
4

3 に答える 3

1

必要なクリーンアップ コードはいつでもクラスのメソッドに入れることができます。__del__

class x:
    def __init__(self):
        self.thing = get_thing()

    def __del__(self):
        self.thing.close()

しかし、あなたはすべきではありません。

これはいくつかの理由で、悪い考えです。cpythonを使用している場合、カスタム__del__メソッドを持つことは、GCが参照サイクルを破ることができないことを意味します。他のほとんどのPython実装を使用している場合、__del__メソッドは予測可能な時間に呼び出されません。

これが、通常、クリーンアップを明示的なメソッドに入れる理由ですclose。それがクラス内でできる最善のことです。クラス自体ではなく、メソッドが呼び出されることを確認するのは、常にクラスのユーザー次第です。close

withしたがって、クラス内でステートメントまたは同等のものを使用する方法はありません。withただし、roippiの回答で説明されているように、クラスをコンテキストマネージャーにするか、ドキュメントで使用することを提案するだけで、クラスのユーザーがステートメントを簡単に使用できるようにすることができcontextlib.closingます。

于 2013-08-07T20:11:48.657 に答える