You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

transitions库中状态转换无效时如何阻止触发器方法执行

问题原因

你遇到的问题根源于重写的_checked_assignment方法的执行顺序:你把自定义业务函数(比如你写的launch、fuel方法)的执行放在了transitions库原生触发器逻辑的前面。而原生触发器的转换合法性校验、MachineError异常抛出逻辑都封装在func参数对应的方法中,所以会出现先执行了你的业务代码、再抛出异常的情况。

解决方案

根据你的业务需求可以选择两种修改方案:

方案1:调整执行顺序(适合自定义逻辑为转换后回调的场景)

如果你的自定义方法不需要在状态转换前执行,只需要在转换成功后运行,直接调换嵌套函数内的执行顺序即可:原生触发器逻辑校验通过、转换成功后才执行业务代码,转换失败抛出异常时不会走到业务逻辑部分。
修改后的_checked_assignment代码如下:

def _checked_assignment(self, model, name, func):
    if hasattr(model, name):
        predefined_func = getattr(model, name)
        def nested_func(*args, **kwargs):
            # 先执行原生触发器逻辑:不合法直接抛出异常,不会执行后续业务代码
            func(*args, **kwargs)
            # 仅转换成功后执行自定义逻辑
            predefined_func(*args, **kwargs)
        setattr(model, name, nested_func)
    else:
        setattr(model, name, func)

方案2:提前校验转换合法性(适合自定义逻辑为转换前回调的场景)

如果你的自定义方法需要在状态转换之前执行,可以通过transitions自动生成的may_<触发器名>方法提前校验转换是否合法,只有校验通过后才执行业务代码和转换逻辑:

def _checked_assignment(self, model, name, func):
    if hasattr(model, name):
        predefined_func = getattr(model, name)
        def nested_func(*args, **kwargs):
            # 提前校验当前状态下是否可以触发该转换
            if not getattr(model, f"may_{name}")(*args, **kwargs):
                # 不合法直接调用原生触发器抛出标准MachineError异常
                func(*args, **kwargs)
            # 合法则先执行前置自定义逻辑,再执行状态转换
            predefined_func(*args, **kwargs)
            func(*args, **kwargs)
        setattr(model, name, nested_func)
    else:
        setattr(model, name, func)

两种方案修改后,你在on_pad状态调用rocket.launch()时,都不会再执行launch方法的打印逻辑,只会直接抛出MachineError异常。

内容的提问来源于stack exchange,提问作者Josh Alexander

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 16:24:02