2011-04-04 40 views
1

我正在设计一个具有撤销/重做功能的类,并且必须临时存储大量数据。我目前正在实现一个“临时”文件,通过重载运行时的文件来删除该文件,但我不得不相信有更好的方法来做到这一点。我尝试过使用tempfile模块,但它不起作用,因为搁置模块需要一个名称,而不是文件对象(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

根据你的代码是如何运行你仍然可能遇到的竞争条件,其中两种不同的工艺获得相同的时间戳和相同的文件名,罕见的,因为这可能是。添加当前的进程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) 
+0

谢谢,这是我应该怎么做文件名伟大的答案。你觉得我怎么摆脱临时文件?我在想,应该有更好的方式,但也许不会。我喜欢使用'/ tmp'目录的想法,出于某种原因,我认为你需要成为root才能到达那里! (我对linux很陌生,并且觉得主目录下面的所有内容都是root)。感谢您让我知道这宝石的信息! – 2011-04-05 00:28:05

+0

不客气,很高兴我能帮上忙。您可以省略__dir ='/ tmp'__参数,它将使用操作系统的默认临时目录(在Unix上恰好是__/tmp__),这是更好的跨平台行为。我认为在这种情况下使用'__del__'是可以的,因为搁架的使用寿命与__DataHandler__有关。在删除搁置文件名之前,您可能还想调用'self._undoredoBuffer.close()'。 – samplebias 2011-04-05 00:39:38

+1

这会导致一个错误'db type could not be determined'。在关闭它之前,你应该在文件中存储一个空的数据库 – 2011-04-05 02:00:06

2

货架使用anydbm检测所使用的数据库的类型在文件中。

你可以在那里创建mkstemp()一个临时文件,并把一个空bsddb(或任何你喜欢),然后通过该文件名搁置