Python 模型已包含一个属性';触发器';。跳过装订

Python 模型已包含一个属性';触发器';。跳过装订,python,state-machine,pytransitions,Python,State Machine,Pytransitions,我想为我的订单模型实现状态机,我正在使用这个漂亮的库。但我面临着这个奇怪的问题 这是我的order.py型号: from order_state_machine import OrderStateMachine class Order(BaseModel): def __init__(self, order_dict): super().__init__(order_dict) # next line basically creates Customer

我想为我的
订单
模型实现状态机,我正在使用这个漂亮的库。但我面临着这个奇怪的问题

这是我的
order.py
型号:

from order_state_machine import OrderStateMachine

class Order(BaseModel):
    def __init__(self, order_dict):
        super().__init__(order_dict)
        # next line basically creates Customer object inside Order model
        self.set('customer', Customer(order_dict['customer']))
        self.machine = OrderStateMachine(self)
这是我的
订单状态机器.py

from transitions import Machine

class OrderStateMachine(Machine):
    order_states = ['pending', 'paid', 'shipped', 'delivered', 'canceled']

    order_transitions = [
        {'trigger': 'pay', 'source': 'pending', 'dest': 'paid'},
        {'trigger': 'deliver', 'source': 'shipped', 'dest': 'delivered'},
        {'trigger': 'cancel', 'source': 'shipped', 'dest': 'canceled'},
    ]

    def __init__(self, order):
        super().__init__(
            model=order,
            states=OrderStateMachine.order_states,
            transitions=OrderStateMachine.order_transitions,
            initial='pending'
        )
当我这样做的时候:

from order import Order

new_order = Order(order_dict)

new_order.state  # returns 'pending'
new_order.pay()
new_order.state  # I expect 'paid'
它,
new\u order.pay()
line,给了我
TypeError:“NoneType”对象是不可调用的
error。而且
模型已经包含了一个属性“trigger”。跳过绑定。
警告,还有很多类似的警告


谁能帮我解决这个问题,可能是图书馆的维护人员。谢谢。

我不能百分之百肯定地说,但我假设您的
基本模型
已经包含了与
转换
想要动态装饰您的模型的方法重叠的属性和方法

transitions
将执行“选中”分配,这意味着当现有属性或方法尚未使用所需名称时,它将仅向模型分配触发器和便利功能。这背后的原因是,有时人们并不关心触发器,只按其名称调用函数(实际上使用
trigger
方法)

我假设您的
BaseModel
包含类似于[1]的属性分配,如下所示

从导入计算机
导入日志记录
类基本模型:
定义初始(自,顺序):
self.pay=None#[1]已定义属性
def触发器(自身):#[2]已定义方法
通过
类OrderStateMachine(机器):
订单状态=[“待定”、“已付款”、“已发货”、“已交付”、“已取消”]
顺序转换=[
{'trigger':'pay','source':'pending','dest':'paid'},
{'trigger':'deliver','source':'shipped','dest':'delivered'},
{'trigger':'cancel','source':'shipped','dest':'cancelled'},
]
定义初始(自我,顺序):
超级()。\uuu初始化__(
型号=订单,
状态=OrderStateMachine.order\u状态,
转换=OrderStateMachine.order\u转换,
首字母“待定”
)
类顺序(基本模型):
定义初始(自,顺序):
super().\uuuu init\uuuuuu(命令)
self.machine=OrderStateMachine(self)
logging.basicConfig(级别=logging.DEBUG)
#[2]将导致“模型已包含属性“触发器”。跳过装订。”
新的顺序=顺序({})
新的_order.state#返回“待定”
#[1]将导致类型错误:“非类型”对象不可调用
新订单。支付()
新建订单状态
要解决这个问题,您应该确保触发器名称和模型属性是互斥的,以防止命名冲突。如果您确实有目的地定义了所有这些方法(例如,在IDE中放置一些代码完成提示),并且确实希望以这种方式保留这些方法,那么您可以覆盖
计算机。\ u checked\u assignment
方法:

class OveriddingMachine(Machine):

    # assign everything to the model ignoring already existing attributes
    def _checked_assignment(self, model, name, func):
        setattr(model, name, func)

请注意,如果您这样做,您的机器可能会以不希望的方式弄乱您的模型。

我认为这与
某些命令有关。你能提供一些你要传递的钥匙的信息吗?如果我省略了一些命令,一切都会顺利进行。@aleneum,首先,感谢您的快速回复。其次,我将其更改为最接近原始代码。@aleneum
order\u dict
是一个JSONDo,您还可以看到“模型已经包含了一个属性‘pay’”。跳过绑定“?@alenum,是的。实际上,我们在BaseModel中既没有
pay
方法,也没有
trigger
方法。但这个解决方案解决了问题。当然,我们将对此进行更多的调查。无论如何,非常感谢@我明白了。因此,值得研究这些属性的来源。可能模型初始化了两次?我在
\u checked\u assignment
上设置了一个断点,查看它实际被调用的位置,并检查当前的模型状态。否则这可能会打中你的膝盖,我完全同意。可能是我们创造了两次。这是一个很大的帮助。再次感谢!!!