临时架子?
我正在设计一个类,这个类需要有撤销和重做的功能,并且要临时存储大量数据。目前,我通过重载del操作符来实现一个“临时”文件,这样当这个类被垃圾回收时,就会删除这个文件。不过我觉得这样做可能还有更好的方法。我尝试过使用tempfile模块,但它不行,因为shelve模块需要的是一个名字,而不是文件对象(真让人烦)。
总之,我想知道有没有人有更好的解决办法。下面是代码的重要部分。
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 个回答
2
shelve使用anydbm来判断文件中使用的数据库类型。
你可以用mkstemp()
创建一个临时文件,然后在里面放一个空的bsddb(或者你喜欢的其他类型),接着把这个文件名传给shelve。
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)