Это зависит от того, что именно означает «отменить».Например, если A, B, C, D и т. Д. Являются произвольными пользовательскими командами и их может быть много в любом порядке, то, скорее всего, вам нужно написать какую-то абстракцию вокруг do / undo.
Если в качестве альтернативы A, B, C, D и т. Д. Представляют собой ресурсы, которые необходимо привести в порядок (соединения с базой данных, файлы и т. Д.), То контекстные менеджеры могут быть более подходящими.
Или, возможно, A, B, CD - это совсем другое.
Небольшой фрагмент кода с использованием менеджеров контекста:
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")