不是所有人都能看涩图 
情景导入 
众所周知,这涩图,十分的珍贵,应该让管理员先看 催涩员(?)
 所以,你写出了这样的代码:
python
@channel.use(
    ListenerSchema(
        listening_events=[GroupMessage],
        decorators=[MatchContent("涩图来")],
    )
)
async def setu(app: Ariadne, member: Member, group: Group):
    if member.permission != MemberPerm.Member:
        ...  # 发涩图1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
这代码,能够正常的运作,很好,但是到了后面,随着 tx 对涩图的打击力度愈发强大, 涩图愈发的稀缺,所以你的判断条件也愈发复杂:
python
@channel.use(
    ListenerSchema(
        listening_events=[GroupMessage],
        decorators=[MatchContent("涩图来")],
    )
)
async def setu(app: Ariadne, member: Member, group: Group):
    if group.id not in [114514, 1919810]:
        await app.send_message(group, MessageChain("对不起,该群并不能发涩图"))
    elif member.id not in [114514, 1919810]:
        await app.send_message(group, MessageChain(At(member.id), "对不起,您的权限并不够"))
    elif frequency(group, member) >= 10:  # 频率判断,详细实现略
        await app.send_message(group, MessageChain(At(member.id), "你太快了,能不能持久点"))
    else:
        async with aiohttp.request("GET", "https://setu.example.com/limit") as r:
            is_max = (await r.json())["is_limit"]
        if is_max:
            await app.send_message(group, MessageChain(At(member.id), "对不起,今天的涩图已经达到上限了哦"))
        else:
            ...  # 获取涩图
            await app.send_message(group, MessageChain(Image(data_bytes=setu)))1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
这种时候问题就大的去了,主要体现在下面几个方面:
- 很乱,在第一眼看过去的时候完全不知道怎么回事
 - 代码重复性极高,但即使做成函数调用,也依然会需要 if 语句
 - 代码有点难修改,需要搞清楚各种 if..else.. 关系
 
那该怎么办?你可以试试 Depend:
python
from graia.broadcast.builtin.decorators import Depend
from graia.broadcast.exceptions import ExecutionStop
def check_group(*groups: int):
    async def check_group_deco(app: Ariadne, group: Group):
        if group.id not in groups:
            await app.send_message(group, MessageChain("对不起,该群并不能发涩图"))
            raise ExecutionStop
    return Depend(check_group_deco)
def check_member(*members: int):
    async def check_member_deco(app: Ariadne, group: Group, member: Member):
        if member.id not in members:
            await app.send_message(group, MessageChain(At(member.id), "对不起,您的权限并不够"))
            raise ExecutionStop
    return Depend(check_member_deco)
def check_frequency(max_frequency: int):
    async def check_frequency_deco(app: Ariadne, group: Group, member: Member):
        if frequency(member.id) >= max_frequency:
            await app.send_message(group, MessageChain(At(member.id), "你太快了,能不能持久点"))
            raise ExecutionStop
    return Depend(check_frequency_deco)
@channel.use(
    ListenerSchema(
        listening_events=[GroupMessage],
        decorators=[MatchContent("涩图来")],
        decorators=[
            check_group(114514, 1919810),
            check_member(114514, 1919810),
            check_frequency(10),
        ],
    )
)
async def setu(app: Ariadne, group: Group):
    async with aiohttp.request("GET", "https://setu.example.com/limit") as r:
        is_max = (await r.json())["is_limit"]
    if is_max:
        await app.send_message(group, MessageChain(At(member.id), "对不起,今天的涩图已经达到上限了哦"))
    else:
        ...  # 获取涩图
        await app.send_message(group, MessageChain(Image(data_bytes=setu)))1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
在第一眼看到这些代码的时候,你是不是满脑子问号(问号脸.jpg), 这不是更长了嘛 kora!别急,让我慢慢讲解……
Depend 是什么 
首先,Depend 是 Graia Broadcast 提供的一种 Decorator。
WARNING
不要将本文提及的 decorator 跟 Python 本身语法中的 decorator 搞混
前面的区域,以后再来探索吧
Depend 的好处 
Depend 好处都有啥,谁说对了就给他。
- 判断的函数被分成了几个部分
 - 大部分的判断都放在了 
decorators参数里面 Listener所需要的参数只有Ariadne实例跟Group实例- 只需要调整 
Decorator顺序就能直接调整判断优先级,而不是改 if..else.. 
怎么用 Depend 写一个 Decorator 
我们先掏出其中的一个 decorator 来详细讲解一下吧:
python
def check_group(*groups: int):
    async def check_group_deco(app: Ariadne, group: Group):
        if group.id not in groups:
            await app.send_message(group, MessageChain("对不起,该群并不能发涩图"))
            raise ExecutionStop
    return Depend(check_group_deco)1
2
3
4
5
6
2
3
4
5
6
首先我们可以看到,我们在 check_group 函数中定义了一个 check_group_deco 函数, 并且返回了 Depend(check_group_deco)。
还记得在QA里讲过,Dispatcher 会解析你所需要的参数吗? 事实上,Depend 所封装的函数也会被 Dispatcher 解析。
而 check_group_deco 这个函数中,当发送消息的群并不在我们所设定的群的时候, 将会发送消息,并且抛出 ExecutionStop 错误。
在 broadcast 接到 ExecutionStop 错误之后,将会中断这个 Listener 的执行。
TIP
事实上,假设你需要 Depend 中被修饰函数的返回值,可以这么写
python
async def check_vip_deco(app: Ariadne, member: Member):
    vip_status = await get_vip(member.id)
    if vip_status is None:
        raise ExecutionStop
    else:
        return vip_status
@channel.use(
    ListenerSchema(
        listening_events=[GroupMessage],
        decorators=[MatchContent("涩图来")],
    )
)
async def setu(app: Ariadne, vip_status = Depend(check_vip_deco)):
    ...1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15