是否可以在装饰器上使用方法?

Is it possible to use methods on decorators?

当我注意到一个装饰器上面有一个方法时,我正在查看 aiortc 示例:

@pc.on("datachannel")
    def on_datachannel(channel):
    ...

我不太明白它是如何工作的或者这段代码有什么作用。我一直在搜索装饰器,我知道可能有 class 个装饰器,但 none 是关于使用方法的。谁能详细说明一下?

@foo
def bar(): ...

此语法只是糖分:

def bar(): ...
bar = foo(bar)

所以,这个:

@pc.on('datachannel')
def on_datachannel(channel): ...

等同于:

def on_datachannel(channel): ...
on_datachannel = pc.on('datachannel')(on_datachannel)

pc 是某个对象,pc.on 是它的一个方法,pc.on('datachannel') 调用它,它 returns 一个函数,pc.on('datachannel')(on_datachannel) 调用返回函数将 on_datachannel 函数传递给它。

pc.on的实现是这样的:

class PC:
    def on(self, event):
        ...
        def wrapper(fn):
            ...
            def inner_wrapper(*args, **kwargs):
                ...
                fn(*args, **kwargs)

            return inner_wrapper

        return wrapper

pc = PC()

所有内部部分完全是一个接受参数的常规装饰器。它是在 class 上定义的,这对它没有影响。