Python 撤消一系列步骤中先前步骤的最佳方法
我试图找到一种更好的方法来执行以下函数。我有一系列需要完成的步骤,如果有任何步骤失败,我需要像这样撤消上一个步骤:Python 撤消一系列步骤中先前步骤的最佳方法,python,optimization,design-patterns,coding-style,Python,Optimization,Design Patterns,Coding Style,我试图找到一种更好的方法来执行以下函数。我有一系列需要完成的步骤,如果有任何步骤失败,我需要像这样撤消上一个步骤: try: A = createA() except: return None try: B = createB(A) except: deleteA(A) return None try: C = createC(B) except: deleteB(B) deleteA(A) return None t
try:
A = createA()
except:
return None
try:
B = createB(A)
except:
deleteA(A)
return None
try:
C = createC(B)
except:
deleteB(B)
deleteA(A)
return None
try:
D = createD(C)
except:
deleteC(C)
deleteB(B)
deleteA(A)
return None
return D
如果可能的话,我不想重复。我该如何改进这一点?是否有一个已知的模式可以遵循
我考虑过的一件事是将
deleteB(
)添加到deleteC()
,并将deleteA()
添加到deleteB()
。这是最好的方法吗?如果您查看一些设计模式,请检查以下内容:
这可能就是你正在寻找的。此外,it命令还可以执行“撤消”操作。如果下面的问题与您的问题类似,请检查该问题 正如评论所指出的,这就是上下文管理器协议的用途。但是,如果您还不想深入了解什么是相当高级的功能,那么您可以在进行时定义
lambda
匿名函数,以记住要整理的内容
try:
deleters = []
A = createA()
deleters.append( lambda: deleteA(A) )
B = createB( A)
deleters.append( lambda: deleteB(B) )
C = createC( B)
deleters.append( lambda: deleteC(C) )
D = createD( C)
return D
except:
for d in reversed( deleters):
d()
return None
这取决于“撤消”的确切含义。例如,如果A、B、C、D等是任意的用户命令,并且可能有大量的命令以任何顺序排列,那么您可能需要围绕do/undo编写某种抽象 如果A、B、C、D等是需要整理的资源(数据库连接、文件等),那么上下文管理器可能更合适 或者A,B,C,D是其他类型的东西 使用上下文管理器的简短代码:
class A:
def __enter__(self):
set things up
return thing
def __exit__(self, type, value, traceback):
tear things down
class B, C and D are similar
def doSomethingThatNeedsToUseD():
try:
with A() as a:
with B() as b:
with C() as c:
with D() as d:
d.doSomething()
except:
print("error")
你要找的是所谓的纪念图案。这是GoF设计模式之一: 在不违反封装的情况下,捕获并外部化对象的内部状态,以便以后可以将对象恢复到此状态
可以找到使用python实现它的一种方法。可以使用的一种模式是上下文管理器,您可以使用上下文管理器,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,用于为您关闭文件的位置。由于Python3.3有contextlib.ExitStack
与上下文管理器相结合来实现这些功能。一种方法是您可以编写一个undo函数,将所有deleteX()
函数包装起来,并像undo([C,B,A])
一样调用它,它解析您的obj以删除并相应地调用deleteX()
。虽然这可能不是最佳的方法。我不知道python,但一些相当于goto的方法实际上是一个很好的解决方案,尽管它不赞成这种方法。有关一般标准,请参见