2

まず、flush メソッドを使用して記録クラスを作成しました。

class Recorder
    def __init__(self, buffer_size, path):
        self._big_buffer = np.array(*buffer_size)
        self._path = path
    def push(self, data):
        # insert in self._big_buffer
        # if self._big_buffer is full:
        #     self._flush()
    def flush(self):
        # write buffer to disk (self._path)

次に、手動で停止したとき、クラッシュしたとき、または何らかの理由で終了時にフラッシュしたかったのです。

だから私は使用しました:

def __init__(self):
    (...)
    atexit.register(self.flush)

そして、それはかなりうまくいきました。

しかし今、私は、別のバッファサイズと別のパスで、記録、記録の停止、再記録を複数回行いたいと考えています。したがって、破棄してから、いくつかをインスタンス化する必要がありRecorderます。ある程度は機能しますが、 oldRecorderのメモリ (いくつかの fat を含むself._big_buffer̀) は によって保持されているため、解放されませんatexit。明示的に呼び出す場合でもdelatexit.unregister(self._flush)Python 3のみなのでできません。

既存のインスタンスを再利用するのではなく、古いインスタンスを破棄して新しいインスタンスを作成したいと考えています。

このような場合、どのように対処しますか?

4

4 に答える 4

4

ハンドラーへの弱い参照を使用してみるとatexit、オブジェクトが他の場所で削除された場合にオブジェクトが保持されなくなります。

import atexit
import weakref

class CallableMethodWeakRef:
    def __init__(self, object, method_name):
        self.object_ref = weakref.ref(object)
        self.method_name = method_name
    def __call__(self):
        object = self.object_ref()
        if object:
            getattr(object, self.method_name)()

class Recorder:
    def __init__(self, *args):
        atexit.register(CallableMethodWeakRef(self, 'flush'))

    def flush(self):
        print 'flushing'

バインドされたメソッドの弱い参照に関する多くの問題を回避するために、メソッドは文字列として渡されます。邪魔になる場合は、いつでも次のBoundMethodWeakrefような実装を使用できます: http://code.activestate.com/recipes/578298-バインドされたメソッドの弱参照/

于 2015-08-19T15:20:34.713 に答える
2

間違ったツールを使用しようとしていると言えます。ステートメント マネージャーとコンテキスト マネージャーは、このwithための非常に優れたツールです。ファイル IO は、ほとんどの python ユーザーが with ステートメントを導入する主な例です。

f = open("somefile.txt", "w")
try:
    f.write("...")
    # more file operations
finally:
    # regardless of what happens, make sure the files is closed 
    f.close()

なる:

with open("somefile.txt", "w") as f:
    f.write("...")
    # more file operations
# close automatically called at the end of the block

__enter__クラスのと__exit__メソッドを記述することで、独自のコンテキスト マネージャーを作成できます。

class Recorder
    def __init__(self, buffer_size, path):
        self._big_buffer = np.array(*buffer_size)
        self._path = path
    def push(self, data):
        # insert in self._big_buffer
        # if self._big_buffer is full:
        #     self._flush()
    def flush(self):
        # write buffer to disk (self._path)
    def __enter__(self):
        return self
    def __exit__(self, exctype, exception, traceback):
        # If an exception was thrown in the with block you will get the details here. 
        # If you want the say that the exception has been handled and for it not to be 
        # raised outside the with block then return True
        self.flush()
        # self.close() ?

Recorder次に、オブジェクトを次のように使用します。

with Recorder(...) as recorder:
    # operations with recorder
    ...
# regardless of what happens the recorder will be flushed at this point
于 2015-08-19T18:40:38.110 に答える