简体   繁体   English

如何使用asyncio使python decorator函数在n秒内重新调度函数?

[英]How can I make a python decorator function to reschedule a function in n seconds using asyncio?

This is my current code: 这是我目前的代码:

import asyncio
import serial


def repeat(seconds):
    def wrap(func):
        def decorated(*args):
            loop = asyncio.get_event_loop()
            loop.call_at(loop.time() + seconds, decorated, *args)
            print('scheduled')
            func(*args)
            return func
        return decorated
    return wrap


@repeat(10)
def send_command(ser, text):
    try:
        if text == 'DATA':
            print("\nSending Data Request")
            ser.write(b'\n022022')
        elif text == 'STAY':
            print("\nInmediate Stay ARM")
            ser.write(b'\n0640010002044D')
        elif text == 'AWAY':
            print("\nInmediate Away ARM")
            ser.write(b'\n0640010003044E')
        elif text == 'DISARM':
            print("\nDISARM")
            ser.write(b'\n0940010001040700055B')
        elif text == 'CHIME':
            print("\nChime toggle")
            ser.write(b'\n0640010007014F')
    except serial.SerialException as e:
        raise e


if __name__ == '__main__':

    ser = serial.Serial('/dev/ttyUSB0', 9600, parity=serial.PARITY_ODD, write_timeout=0, timeout=0)

    loop = asyncio.get_event_loop()
    loop.call_at(loop.time() + 5, send_command, ser, 'DATA')
    loop.run_forever()

In this example I'm trying to schedule the send_command function to run in 5 seconds and every 10 seconds afterwards. 在这个例子中,我试图安排send_command函数在5秒内运行,之后每隔10秒运行一次。 It seems to work but I'm a bit confused with the loop.call_at(loop.time() + seconds, decorated, *args) call. 它似乎工作,但我对loop.call_at(loop.time() + seconds, decorated, *args)调用有点困惑。 Any comments will be appreciated. 任何意见将不胜感激。

Your code is fine (except as noted you should return func's result inside decorator), I improved it a bit. 你的代码很好(除非你注意到你应该在装饰器中返回func的结果),我对它进行了一些改进。

It's easier to see and test with synthetic example: 使用合成示例更容易查看和测试:

import asyncio
import functools


def repeat(seconds):
    def wrap(func):
        @functools.wraps(func)  # see http://stackoverflow.com/q/308999/1113207
        def decorated(*args, **kwargs):
            # We should call func that decorated again to
            # force decorator's `call_at` code to execute again:
            loop = asyncio.get_event_loop()
            loop.call_at(
                loop.time() + seconds, 
                functools.partial(decorated, *args, **kwargs)  # see http://stackoverflow.com/q/3252228/1113207
            )
            # We should return result of func's excecution:
            return func(*args, **kwargs)
        return decorated
    return wrap


@repeat(2)
def send_command():
    print('send_command')


async def main():
    send_command()  # call once, rescheduling started

    for i in range(10):
        print(i)
        await asyncio.sleep(1)


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())

Output: 输出:

send_command
0
1
send_command
2
3
send_command
4
5
send_command
6
7
send_command
8
9
send_command
[Finished in 10.3s]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 asyncio 在 python 中每 n 秒运行一个函数 - Run a function every n seconds in python with asyncio Python如何使用asyncio使function同时运行 - Python How to make function run simultaneously using asyncio 如何使用 aysncio 在 python 中每隔 n 秒执行一次 function - How to execute a function every n seconds in python using aysncio 如何使类装饰器不中断isinstance函数? - How can I make a class decorator not break isinstance function? 使用 python-asyncio,我如何读取 url 而不是在主 function 中列出 url? - Using python-asyncio, how can I read the urls instead of listing the urls inside the main function? 如何在python装饰器中以编程方式更改函数*不*的argspec? - How can I programmatically change the argspec of a function *not* in a python decorator? 如何在 Python 中为这个简单的函数编写装饰器? - How can I write a decorator for this simple function in Python? 如何以编程方式更改python装饰器中函数的argspec? - How can I programmatically change the argspec of a function in a python decorator? 如何将我的 function 更改为装饰器 python? - how i can change my function into decorator python? Python:如何使用装饰器向 function 添加 doxygen 注释? - Python: How can I add a doxygen comment to a function with a decorator?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM