Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何等待对象更改状态_Python_Python 3.5_Python Asyncio - Fatal编程技术网

Python 如何等待对象更改状态

Python 如何等待对象更改状态,python,python-3.5,python-asyncio,Python,Python 3.5,Python Asyncio,在我的async处理程序中,我希望等待任务的状态发生更改。现在,我只是在无休止的循环中检查状态并等待。下面是一个示例,wait_until_done函数: import asyncio class LongTask: state = 'PENDING' my_task = LongTask() def done(): my_task.state = 'DONE' async def wait_until_done(): while True:

在我的
async
处理程序中,我希望等待任务的状态发生更改。现在,我只是在无休止的循环中检查状态并等待。下面是一个示例,
wait_until_done
函数:

import asyncio


class LongTask:
    state = 'PENDING'

my_task = LongTask()


def done():
    my_task.state = 'DONE'

async def wait_until_done():
    while True:
        if my_task.state == 'PENDING':
            await asyncio.sleep(2)
        else:
            break
    print("Finally, the task is done")


def main(loop, *args, **kwargs):
    asyncio.ensure_future(wait_until_done())
    loop.call_later(delay=5, callback=done)

loop = asyncio.get_event_loop()
main(loop)
loop.run_forever()

有更好的方法吗?

只是为了避免混淆:我想你不是在说,而是在说一些可变状态,对吗

在这种情况下,您可以等待异步更改某些内容

如果您需要在两种状态之间切换,这可能是您想要的。下面是一个小例子:

import asyncio


my_task = asyncio.Event()


def done():
    my_task.set()



async def wait_until_done():
    await my_task.wait()  # await until event would be .set()
    print("Finally, the task is done")


async def main():
    loop.call_later(delay=5, callback=done)
    await wait_until_done()


loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(main())
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()
Upd:

保持
长任务
接口的更复杂示例:

import asyncio



class LongTask:
    _event = asyncio.Event()

    @property
    def state(self):
        return 'PENDING' if not type(self)._event.is_set() else 'DONE'

    @state.setter
    def state(self, val):
        if val == 'PENDING':
            type(self)._event.clear()
        elif val == 'DONE':
            type(self)._event.set()
        else:
            raise ValueError('Bad state value.')

    async def is_done(self):
        return (await type(self)._event.wait())

my_task = LongTask()


def done():
    my_task.state = 'DONE'



async def wait_until_done():
    await my_task.is_done()
    print("Finally, the task is done")


async def main():
    loop.call_later(delay=5, callback=done)
    await wait_until_done()


loop = asyncio.get_event_loop()
try:
    loop.run_until_complete(main())
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()

观察者模式可能就是您想要使用的。使对象“可观察”,然后注册一个处理程序作为对象的观察者,这样当状态更改时,它将调用您想要的任何方法。是的,任务是常规对象,而不是asyncio.task。我考虑过Event(),但您的解决方案不合适:长话短说,我不能触摸
done
func,它应该只是更改任务的状态。@Sergeybelah,我添加了另一个保持
done
func不变的示例。