如何在 api 调用期间雄辩地跟踪所有 warnings/messages 和 return 以及 python 中的输出?

How to eloquently keep a track of all warnings/messages during an api call and return the same along with the output in python?

方法一

warnings = list()
messages = list()

def calculate(a, b, method):
    if isinstance(a, float):
        warnings.append(f"a:{a} is float, converting it to int!")
        a = int(a)
    ...
    result = a + b
    messages.append(f"result is {result}")
    return result, {"warnings": warnings, "messages": messasges}

在上面的例子中,我有一个简单的函数 calculate() 并且我在这个 运行 期间跟踪所有 warnings/messages 然后返回相同的实际结果因为让我们假设我想在 UI 上向最终用户显示这些 warnings/messages 以及实际结果。

另一种更好的方法是:

方法二

class Alerts():
    def __init__():
        self.warnings = list()
        self.messages = list()

def calculate(a, b, method):
    alrt = Alerts()
    if isinstance(a, float):
        alrt.warnings.append(f"a:{a} is float, converting it to int!")
        a = int(a)
    ...
    result = a + b
    alrt.messages.append(f"result is {result}")
    return result, alrt

在方法 2 中,通过在单个对象中定义它们来更方便地跟踪所有 messages/warnings,这也将允许在 Alert() class 中编写一些自定义方法来格式化messages/warnings,等等。

潜在问题

如果在一个 api 调用中涉及多个方法调用,那么我将不得不 create/maintain 这个 Alert() 对象随处可见 and/or 在我的方法中到处乱扔它以保持一个对象中所有 warnings/messages 的轨迹。

以上方法之一是实现此目的的好方法吗?能再多eloquent吗?

谢谢!

经过一番思考,下面是我能想到的最多 eloquent 的方法。 calculate() 是我的 api 函数,sum() 是 api 运行.

中的内部方法调用之一
# for handling results of any api, including errors/warnings/messages
class ResultHandler():
    def __init__(self):
        self.warnings = list()
        self.messages = list()
        self.errors = list()
        self.result = dict()

    def append_traceback(self):
        pass

# to wrap the output of an api call in ResultHandler() object
def wrap_output(func):
    def wrapper(*args, **kwargs):
        rh = ResultHandler()
        rh.messages.append("1: i am wrap_output!")
        try:
            kwargs["rh"] = rh
            rh.result = func(*args, **kwargs)
        except:
            rh.append_traceback()
        rh.messages.append("2: i am wrap_output!")
        return rh
    return wrapper

# an internal method call
def sum(rh):
    print("sum")
    rh.messages.append("i am sum!")
    return 1

# api function
@wrap_output
def calculate(*args, **kwargs):
    rh = kwargs["rh"]

    rh.messages.append("1: i am calculate!")

    out = sum(*args, **kwargs)

    rh.messages.append("2: i am calculate!")
    return out

# calling api
o = calculate()
print(o.messages)