Python 如何装饰:';撤消';通过复制try-except语句中的更改
我希望在输入异常时,首先通过副本上的设置“撤消”try语句中的更改,并且仅当成功地用该副本覆盖原始副本时。我似乎有一个解决方案,但不知道如何把它变成一个装饰器,使我的代码保持干燥 举例说明:Python 如何装饰:';撤消';通过复制try-except语句中的更改,python,exception,decorator,Python,Exception,Decorator,我希望在输入异常时,首先通过副本上的设置“撤消”try语句中的更改,并且仅当成功地用该副本覆盖原始副本时。我似乎有一个解决方案,但不知道如何把它变成一个装饰器,使我的代码保持干燥 举例说明: a = 0 try: a = 1 1/0 except: pass print(a) 输出:1(我希望它是0) 用于处理我在此处找到的方法中的异常的装饰器: 上面引用的装饰器如下所示: def handle_exceptions(f): def wrapper(*arg
a = 0
try:
a = 1
1/0
except:
pass
print(a)
输出:1(我希望它是0)
用于处理我在此处找到的方法中的异常的装饰器:
上面引用的装饰器如下所示:
def handle_exceptions(f):
def wrapper(*args, **kw):
try:
return f(*args, **kw)
except Exception as e:
raise e # or do w/e
return wrapper
如果我使用这个:
class A:
def __init__(self):
self.items = []
def add_something(item):
try:
self.items.append(item)
1/0
except Exception as e:
raise e
然后该项目将被添加到项目列表中(例如,在触发异常之前发生状态更改)
“add_something”方法(我目前使用的方法)可防止出现这种情况,尝试首先在副本上设置它,如果成功,将覆盖原始文件:
class A:
def __init__(self):
self.items = []
def add_something(item):
a_copy = self.items.copy()
try:
a_copy.append(item)
1/0 # fails here, state of self.items remains unchanged
except Exception as e:
raise e
else: # in case no exception is hit, overwrite
self.items = a_copy
这很有效。但是,我需要重复很多次,因此我更喜欢一个处理这个问题的装饰师,这样“add_something”方法可以保持干净,理想情况如下(或任何最接近的方法):
我希望有一个decorator,@exception\u处理程序,它可以实现与上面包含try/except/else语句的代码片段中相同的行为,以保持我的类方法干净明了。我认为decorator不是正确的解决方案。 1.不同的方法不会有相同的撤销要求,因此装饰程序必须使用撤销函数作为参数。 2.即使这样做,撤消方法也可能无法访问您在try块中修改的变量
我认为更好的方法是编写一个抽象类(我们称之为
Task
),它有Run
和Undo
方法,但尚未实现。然后,您可以编写一个将此类的对象作为输入的方法,在try块中执行Run
方法,在except块中执行Undo
。这样做的好处是类可以包含共享变量,这样Run
和Undo
都可以访问它。为什么不在赋值之前检查赋值是否有效?这应该比从头开始实现事务要容易得多。我同意-用装饰器实现这一点没有什么好办法(如果你只处理数据结构,你可以先进行深度复制,然后再进行递归复制,但用类是不可行的)。
@exception_handler
def add_something(item):
self.items.append(item)
1/0