二十八 Home Assistant 各种的函数

函数分类

在Home Assistant中,一项工作由一个将被调用的函数表示。它将在我们的事件循环或线程池中运行,具体取决于它是否是异步安全的。

Home Assistant使用的约定是,所有必须在事件循环内运行的函数都以 async_ 为前缀。

协程函数

协程是基于Python生成器语法的特殊函数,允许它们在等待结果时暂停执行。

调用协程函数将返回一个生成器对象,但实际上不会开始执行。这个对象将在从另一个协程中 yield 出来或者被调度到事件循环中时执行任务。

要声明一个函数为协程,从 asyncio 包中导入协程注释并注释你的函数。

import asyncio

@asyncio.coroutine
def async_look_my_coroutine(target):
    result = yield from entity.async_turn_on()
    if result:
        print("hello {}".format(target))

hass.loop.create_task(async_look_my_coroutine("world"))

在这个例子中,我们通过调用 hass.loop.create_task 来调度协程。这将把协程添加到要运行的任务队列中。当事件循环运行 async_look_my_coroutine 时,当调用 yield from entity.async_turn_on() 时,它将暂停任务。此时,将调度一个新任务来执行 entity.async_turn_on()。当那个任务执行完成后,async_look_my_coroutine 将恢复执行。

回调函数

这是一个普通函数,被认为可以在事件循环内安全运行。回调函数不能暂停自己,因此不能进行任何I/O操作或调用协程。回调函数可以调度一个新任务,但不能等待结果。

要声明一个函数为回调函数,从核心包中导入回调注释并注释你的函数。

在Home Assistant中,回调函数的一个常见用例是作为事件或服务调用的监听器。它可以处理传入的信息,然后调度正确的调用。以下是来自自动化组件的示例。

from homeassistant.core import callback

@callback
def async_trigger_service_handler(service_call):
    """处理自动化触发服务调用。"""
    vars = service_call.data.get(ATTR_VARIABLES)
    for entity in component.async_extract_from_service(service_call):
        hass.loop.create_task(entity.async_trigger(vars, True))

在这个例子中,entity.async_trigger 是一个协程函数。调用协程函数将返回一个协程任务。传入的参数将在任务执行时使用。

要执行任务,我们必须将其调度到事件循环上执行。这是通过调用 hass.loop.create_task 来完成的。

为什么要有回调函数?

你可能会想,如果协程可以做回调函数能做的所有事情,为什么还要有回调函数呢?原因是性能和核心API对象更好的状态一致性。

当协程A等待协程B时,它将暂停自己并调度一个新任务来运行B。这意味着事件循环现在正在运行A、B,然后再运行A。如果B是一个回调函数,A将永远不必暂停自己,因此事件循环只是在运行A。一致性的含义是,排队在事件循环上运行的其他事件将继续等待,直到回调函数完成,但在让步给另一个协程时会交错执行。

事件循环和线程安全

这些函数在线程和事件循环中都可以安全运行。这些函数通常执行计算或在内存中转换数据。任何进行I/O操作的函数都不属于这个类别。许多标准库函数属于这个类别。例如,使用 sum 计算一组数字的总和或合并两个字典。

没有特殊的注释来标记函数属于这个类别,在从事件循环内部使用这些函数时应该小心。如果有疑问,查看它们的实现。

其他函数

这些是所有不属于前面类别的函数。这些函数要么是线程安全的,要么不被认为可以在事件循环内安全运行。这些是使用 sleep 或执行I/O操作的函数。

不需要特殊注释就被认为属于这个类别。

总结

本文主要介绍了Home Assistant中函数的分类,包括协程函数、回调函数、事件循环和线程安全函数以及其他函数。协程函数基于Python生成器语法,可暂停执行等待结果,需用 asyncio.coroutine 注释;回调函数普通且安全,可处理信息和调度任务,用 callback 注释;事件循环和线程安全函数可在线程和事件循环中安全运行,多为计算或数据转换类,无特殊注释;其他函数不属于上述类别,如使用 sleep 或执行I/O操作的函数,也无特殊注释。同时解释了回调函数存在的原因是性能和状态一致性考虑。在使用各类函数时需注意其特性和适用场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值