0

我的问题其实很简单,但是我对pytransition代码并不精通,无法自己找到答案:

是否可以仅将 AsyncGraphMachine 与 async on_enter 回调一起使用。

在文档中:https ://github.com/pytransitions/transitions#-using-async-callbacks 指出:

如果您使用的是 Python 3.7 或更高版本,则可以使用 AsyncMachine 处理异步回调。如果愿意,您可以混合使用同步和异步回调,但这可能会产生不希望的副作用。请注意,需要等待事件,并且事件循环也必须由您处理。

我正在使用 python > 3.7,我无法让我的样本工作:

from transitions.extensions.asyncio import AsyncMachine
import asyncio
import time
from transitions import State


class AsyncModel:

    async def do_async(self):
        print("Do async start")
        await asyncio.sleep(5)
        print("Do async end")

    def do_sync(self):
        print("Do async start")
        time.sleep(5)
        print("Do async end")

transitions = [dict(trigger="start", source="*", dest="initialization"),
               dict(trigger="finish", source="initialization", dest="final")]
states = [State(name="initialization", on_enter=["do_async", "do_sync"]),
          State(name="final", on_enter=["do_async", "do_sync"])]

model = AsyncModel()
machine = AsyncMachine(model, states=states, transitions=transitions)

asyncio.get_event_loop().run_until_complete(model.start())

实际错误是:

    /home/user/.local/lib/python3.8/site-packages/transitions/core.py:128: RuntimeWarning: coroutine 'AsyncMachine.callbacks' was never awaited
      event_data.machine.callbacks(self.on_enter, event_data)       RuntimeWarning: Enable tracemalloc to get the object allocation traceback       Traceback (most recent call last):
      File "./test.py", line 27, in <module>
        asyncio.get_event_loop().run_until_complete(model.start())
      File "/usr/lib/python3.8/asyncio/base_events.py", line 616, in run_until_complete
        return future.result()
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 177, in trigger
        return await self.machine.process_context(func, _model)
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 409, in process_context
        res = await self._process(func, model)
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 443, in _process
        return await trigger()
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 192, in _trigger
        return await self._process(event_data)
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 201, in _process
        if await trans.execute(event_data):
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 130, in execute
        await self._change_state(event_data)
      File "/home/user/.local/lib/python3.8/site-packages/transitions/extensions/asyncio.py", line 145, in _change_state
        await event_data.machine.get_state(self.dest).enter(event_data)         TypeError: object NoneType can't be used in 'await' expression

但是,根据文档本身,on_enter 类型的函数是回调:https ://github.com/pytransitions/transitions#state-callbacks

所以我想知道这里发生了什么。

预先感谢您的帮助

编辑:好的,问题甚至可能出现在我什至不会考虑的地方:

from transitions.extensions.asyncio import AsyncMachine
import asyncio
import time
from transitions import State


class AsyncModel:

    async def do_async(self):
        print("Do async start")
        await asyncio.sleep(5)
        print("Do async end")

    def do_sync(self):
        print("Do sync start")
        time.sleep(5)
        print("Do sync end")

transitions = [dict(trigger="start", source="initialization", dest="final", before=["do_async", "do_sync"], after=["do_sync"], prepare=["do_sync"])]
states = [State(name="initialization"),
          State(name="final")]

model = AsyncModel()
machine = AsyncMachine(model, states=["initialization", "final"], transitions=transitions, initial="initialization")

asyncio.get_event_loop().run_until_complete(model.start())

这是有效的,但是这是失败的:

from transitions.extensions.asyncio import AsyncMachine
import asyncio
import time
from transitions import State


class AsyncModel:

    async def do_async(self):
        print("Do async start")
        await asyncio.sleep(5)
        print("Do async end")

    def do_sync(self):
        print("Do sync start")
        time.sleep(5)
        print("Do sync end")

transitions = [dict(trigger="start", source="initialization", dest="final", before=["do_async", "do_sync"], after=["do_sync"], prepare=["do_sync"])]
states = [State(name="initialization"),
          State(name="final")]

model = AsyncModel()
machine = AsyncMachine(model, states=states, transitions=transitions, initial="initialization")

asyncio.get_event_loop().run_until_complete(model.start())

看起来转换中的普通状态与异步机器不兼容,您应该改用“from transitions.extensions.asyncio import AsyncState”

4

1 回答 1

0

好的,实际上我通过反复试验找到了答案,我的问题是我使用的是 State 而不是 AsyncState

于 2022-02-02T22:12:19.487 回答