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