我正在使用以下模型:

import time

class A:
    def do_action_1(self):
        print("A: action 1")

    def do_action_2(self):
        print("A: action 2")
        raise Exception

class B:
    def __init__(self,A):
        self.a = A
        self.status = None

    def call_action_1(self):
        self.a.do_action_1()

    def call_action_2(self):
        self.a.do_action_2()

a = A()
b = B(a)

while True:
    try:
        print("call action 1")
        b.call_action_1()
        print("call action 2")
        b.call_action_2()
    except Exception as e:
        print ("exception catched")
        while True:
            try:
                b.call_action_2()
                break
            except Exception:
                print ("exception catched")
                print ("waiting 3s ...")
                time.sleep(3)

当从B内部调用的b.status引发异常时,我需要以某种方式修改a.do_action_2b.call_action_2在不同的地方被多次调用,因此硬编码try except不是我想要的,也不是一种优雅。我试图使用某种装饰器,但我一直失败。看起来我缺少什么。

如果您有任何建议,请告诉我。也欢迎对设计发表任何意见。

问候

Ĵ

最佳答案

我不能完全确定我是否理解您的问题,但是会遇到麻烦。

装饰器的一般想法是,您想向已经喜欢的类添加行为,但由于某种原因不能直接更改。

基本上,您希望将一个新类包装在原始类周围,并赋予其其他行为。

这样做时,您希望将尽可能多的新功能 push 新的装饰器中,从而不必在其他任何地方更改代码。

在您的示例中,最大的问题是状态是B类的一部分,而不是A类。您还希望将所有重试逻辑移到B类中。

它可能看起来像这样:

import time

class A:
    def do_action_1(self):
        print("A: action 1")

    def do_action_2(self):
        print("A: action 2")
        raise Exception

class B:
    def __init__(self,A):
        self.a = A
        self.status = 'None'

    def call_action_1(self):
        self.a.do_action_1()

    def call_action_2(self):
        while self.status != 'Success':
            try:
                self.a.do_action_2()
                self.status = 'Success'
            except Exception as e:
                self.status = 'Failure'
                print("exception caught inside decorator B")
                print("> waiting 3s ...")
                time.sleep(3)
            ## some sort of safety maximum attempt should be implemented so you don't get into an infinite loop here.

a = A()
b = B(a)

while True:
    try:
        print("call action 1")
        b.call_action_1()
        print("call action 2")
        b.call_action_2()
    except Exception as e:
        print("exception in main")

为了安全起见,您应该为B类实现某种最大尝试次数,以使它在X尝试do_action_2()之后停止尝试。

关于python - 在python中使用装饰器进行错误处理,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47419199/

10-13 07:31