1

I am designing a class that has undo/redo functionality and has to temporarily store a lot of data. I'm currently implementing a "temporary" file by overloading the del operator to delete the file when the class is garbage collected, but I have to believe there is a better way to do this. I have tried using the tempfile module, but it doesn't work because the shelve module expects a name, not a file object (grr).

Anyway, was wondering if anyone had a better way to do this. Important parts of the code are below.

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

根据您的代码的运行方式,您仍然可能会遇到竞争条件,即两个不同的进程获得相同的时间戳和相同的文件名,这种情况可能很少见。添加当前进程 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 回答