Временные полки?

Я разрабатываю класс, который имеет функции отмены / повтора и должен временно хранить много данных. В настоящее время я реализую "временный" файл, перегрузив оператор 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

2 ответа

Решение

В зависимости от того, как выполняется ваш код, вы все равно можете столкнуться с условием гонки, когда два разных процесса получают одну и ту же метку времени и одно и то же имя файла, что может быть редко. Добавление текущего идентификатора процесса поможет смягчить эту проблему, но я бы порекомендовал вам использовать модуль 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)

Полка использует anydbm для определения типа базы данных, используемой в файле.

Вы можете создать временный файл с mkstemp() и поместите туда пустую bsddb (или что вы предпочитаете) и затем передайте это имя на полку

Другие вопросы по тегам