Асинхронный декоратор в классе

Как сделать асинхронный декоратор в классе? Я попробовал реализовать, но возникает проблема, которую я не могу решить.

import asyncio
from functools import wraps

class sa(object):
    def a(self, fun):
        @wraps(fun)
        async def wrapper(*args):
            print(args)
            return await fun(*args)
        return wrapper

    @a
    async def b(self, text):
        print(text)
        return False


n = sa()
asyncio.get_event_loop().run_until_complete(n.b('hello'))

Ответы (2 шт):

Автор решения: gil9red

Как вариант, можно вынести функцию из класса, тогда не нужно будет передавать self:

import asyncio
from functools import wraps


def a(fun):
    @wraps(fun)
    async def wrapper(*args):
        print(args)
        return await fun(*args)

    return wrapper


class sa(object):
    @a
    async def b(self, text):
        print(text)
        return False


n = sa()
asyncio.get_event_loop().run_until_complete(n.b('hello'))

Вывело:

(<__main__.sa object at 0x000001BF26808DD8>, 'hello')
hello

PS.

Можно и внутри класса оставить, но это может привести к путанице:

class sa(object):
    def a(fun):
        @wraps(fun)
        async def wrapper(*args):
            print(args)
            return await fun(*args)

        return wrapper

    @a
    async def b(self, text):
        print(text)
        return False

PPS.

Еще можно так оформить декоратор, и вызывать его для других функций:

import asyncio
from functools import wraps

class sa(object):
    def a(self, fun):
        @wraps(fun)
        async def wrapper(*args):
            print(args)
            return await fun(*args)

        return wrapper

n = sa()

@n.a
async def b(text):
    print(text)
    return False

asyncio.get_event_loop().run_until_complete(b('hello'))

Результат:

('hello',)
hello
→ Ссылка
Автор решения: eri
class sa(object):
    def a(fun):
        @wraps(fun)
        async def wrapper(self, *args):
            print(self)
            print(args)
            return await fun(self, *args)

        return wrapper

    @a
    async def b(self, text):
        print(text)
        return False
→ Ссылка