我正在为个人项目制作资产管理系统。我的问题是如何干净有效地处理Python中的文件系统操作,以便我可以在出现问题时回滚或撤消。
典型的操作看起来像这样
try
file system operation(s)
update database
except Exceptions
undo file system operations already performed
rollback database transaction
handle exceptions
文件系统操作可以是创建,复制,链接和删除文件/目录
之类的东西我的想法是为文件系统操作和数据库管理都有上下文管理器。执行将是这样的:
# create new asset
with FileSystemCM as fs, DatabaseCM as db:
fs.create_dir(path_to_asset)
fs.create_file(path_to_a_file_this_asset_needs)
db.insert('Asset_Table', asset_name)
现在,如果例如db.insert使FileSystemCM删除新创建的文件和新创建的目录,并且Databasecm将DB Transaction倒退
对我的FileSystemCM实现的一种简单方法将是这样的:
class FileSystemCM(object):
""" File System Context Manager """
def __init__(self):
self.undo_stack = [] # list of (fn, args, kwargs)
def __enter__(self):
return self
def __exit__(self, exception_type, exception_val, traceback):
if exception_type:
# pop undo actions off the stack and execute
while self.undo_stack:
undo_fn, args, kwargs = self.undo_stack.pop()
undo_fn(*args, **kwargs)
def create_dir(self, dir_path):
create_file(dir_path)
self.undo_stack.append((remove_dir, [dir_path], {'force': True}))
def create_file(self, file_path):
create_file(file_path)
self.undo_stack.append((remove_file, [file_path], {'force': True}))
有更好的方法吗?在某些情况下,我可以在
上使用反馈来处理这种实现。删除文件。我的想法是将文件移动到临时位置(或创建TMP硬链接),如果一切顺利,请删除临时文件或链接,否则将其恢复。但这可能会导致下面的情况。
__EXIT __代码抛出例外并没有完成撤消操作,也许我留下日志文件,以便至少可以手动清理操作?
我的意思是评论,但它太长了,无法适应评论部分。首先,让我说这听起来像一个非常有趣的项目(至少对于我的口味)。
某个时候(我不记得在哪里)我读过一篇文章,内容是有关实现撤消/重做功能的文章,而他们所做的是维护两个单独的堆栈(一个用于撤消,一个用于重做)。当用户执行操作时,将其参数推入撤消堆栈时,一对动作/ITS逆转。每当用户执行撤消操作时,对两对的反向操作都会执行,然后将对将对重做堆栈移动到重做堆栈中,并且执行重做操作时,将执行该对的操作,并将对将两对置于撤消堆栈中。
每当用户执行新操作时,重做堆栈就会被清除。这种方法的唯一吸引力是不可逆转的动作。我可以想到的一种方法是要使用某种事件源模式,使您保持整个系统及其差异。这似乎很低效率,但通常在软件中使用。