谁在找我 
WARNING
以下使用场景,只能在 Graia Saya 模块中才有所体现
我们来仔细对比一下 Graia Saya 与 BCC 中对于 listener 的用法
python
# BCC
@bcc.receiver(GroupMessage)
# saya
@channel.use(ListenerSchema(listening_events=[GroupMessage]))1
2
3
4
2
3
4
你会发现,channel.use 传入的事件是一个 List[Events], 而不像 bcc.receiver 一样,是一个 Events。
事实上,BCC 的广播确实是支持多类型的虽然 bcc.receiver 不行
TIP
以下例子全部都只能在 saya 中使用。 假设你用的是 bcc.receiver,还是跳过这一章节吧。
举个例子 
python
from typing import Union
@channel.use(ListenerSchema(listening_events=[GroupMessage, NudgeEvent]))
async def hello(app: Ariadne, group: Group, member: Member, event: Union[GroupMessage, NudgeEvent]):
    if isinstance(event, NudgeEvent) or At(app.account) in event.message:
        await app.send_message(group, MessageChain("找我干肾么"))1
2
3
4
5
6
7
2
3
4
5
6
7
当然,以上还只是最简答的例子。更多的例子是同时包含 FriendMessage 和 GroupMessage 这种情况,不是吗? 但是问题来了, GroupMessage 的情况下,你能获取 Group 和 Member 这两个类, 而在 FriendMessage 的情况下,你只能获取到 Friend 这个类。
python
@channel.use(ListenerSchema(listening_events=[GroupMessage, FriendMessage]))
async def test(app: Ariadne, group: Group, friend: Friend, message: MessageChain):
    ...1
2
3
2
3
如果你这样做,不管是接收 GroupMessage 还是 FriendMessage,你都会因为无法成功解析其中一个 type hint 而产生报错
但是,既然都用了 Ariadne 了,你肯定不想跟个傻子一样,通过获取事件本身来获取你所需要的参数,不是吗?那么就有了下面这些例子。
python
from typing import Union
@channel.use(ListenerSchema(listening_events=[GroupMessage, FriendMessage]))
async def hello(app: Ariadne, sender: Union[Group, Friend], message: MessageChain):
    if str(message) == "你好":
        await app.send_message(sender, MessageChain("你好,怎么了?"))1
2
3
4
5
6
2
3
4
5
6
python
@channel.use(ListenerSchema(listening_events=[GroupMessage, FriendMessage]))
async def hello(app: Ariadne, sender: Group | Friend, message: MessageChain):
    if str(message) == "你好":
        await app.send_message(sender, MessageChain("你好,怎么了?"))1
2
3
4
2
3
4
现在,Ariadne 已经支持了如下的 type hint
- typing.Union (在 
Python 3.10+中,Union[a, b]与a | b等价) - typing.Optional (与 
Union[a, None]a | None等价) - typing.Annotated (
Python3.9新功能)