1

元に戻す/やり直し機能があり、一時的に大量のデータを保存する必要があるクラスを設計しています。私は現在、クラスがガベージコレクションされたときにファイルを削除するためにdel演算子をオーバーロードすることによって「一時」ファイルを実装していますが、これを行うためのより良い方法があると信じなければなりません。tempfileモジュールを使用してみましたが、shelveモジュールがファイルオブジェクト(grr)ではなく名前を予期しているため、機能しません。

とにかく、誰かがこれを行うためのより良い方法があるかどうか疑問に思っていました。コードの重要な部分は以下のとおりです。

import os, shelve
from time import time
class DataHandlerUser(DataHandler):
   def __init__(self, data):
      # storing items
      self.__unredofilename = os.path.dirname(__file__) + '/.undoredo' + str(time()) + '.pyworkbooks'
      try:
         os.remove(self.__unredofilename)
      except OSError: pass

      self._undoredoBuffer = shelve.open(self.__unredofilename)
      # ... rest of init


   def __del__(self):
      # simple check to make sure not tampered with
      if '.undoredo' not in self.__unredofilename or '.pyworkbooks' not in self.__unredofilename:
         raise Exception('Critical Error: Internal filename for undo/redo operations tampered with')
      try:
         os.remove(self.__unredofilename)
      except OSError: pass
4

2 に答える 2

4

コードの実行方法によっては、2つの異なるプロセスが同じタイムスタンプと同じファイル名を取得するという競合状態が発生する可能性があります。現在のプロセスIDを追加すると、これを軽減するのに役立ちますが、tempfileモジュールを使用し続けることをお勧めします。

一時ファイルの名前だけが必要な場合は、ファイル名を使用する前に、 tempfile.mkstempを使用して、返されたファイル記述子を閉じることができます。

import os, tempfile
fd, self._undo_fname = tempfile.mkstemp(suffix='.undoredo', dir='/tmp')
os.close(fd)
self._undo_buffer = shelve.open(self._undo_fname)
于 2011-04-04T23:49:41.240 に答える
2

shelveはanydbmを使用して、ファイルで使用されているデータベースのタイプを検出します。

で一時ファイルを作成しmkstemp()、そこに空のbsddb(または任意のもの)を入れて、そのファイル名を棚に渡すことができます

于 2011-04-04T23:58:18.063 に答える