我的问题其实很简单,但是我对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”