Como faço para que decoradores baseados em classe funcionem, por exemplo, métodos? [duplicado]

Esta pergunta já tem uma resposta aqui:

Usando classes como decoradores de métodos [duplicado] 1 resposta

Existem duas maneiras de chamar os decoradores: 1) passando a função / classe do decorador

class Foo(object):
    def __init__(self):
        self.x = 1

    @foo_decorator
    def bar(self, x):
        return self.x + x

ou 2) passando o valor de retorno da função decoradora / instância de classe.

class Foo(object):
    def __init__(self):
        self.x = 1

    @foo_decorator("args")
    def bar(self, x):
        return self.x + x

A questão é: como faço para que o decorador funcione nos dois casos, já que preciso implementar o decorador usando o método baseado em classe?

Um exemplo dessa implementação seria

import functools

class FooDecorator(object):
    def __init__(self, *args):
        if len(args) == 1 and callable(args[0]):
            self.f = args[0]
            functools.update_wrapper(self, args[0])
        else:
            self.f = None

    def __call__(self, *args, **kwargs):
        if self.f is not None:
            return self.f(*args, **kwargs)
        else:
            assert len(args) >= 1 and callable(args[0])
            f = args[0]
            self.f = f
            functools.update_wrapper(self, f)

            return self

foo_decorator = FooDecorator

No entanto, testar essa implementação simples usando o código a seguir gera alguns erros:

class Foo1(object):
    def __init__(self):
        self.x = 1

    @foo_decorator
    def bar(self, x):
        return self.x + x

class Foo2(object):
    def __init__(self):
        self.x = 1

    @foo_decorator("args")
    def bar(self, x):
        return self.x + x


Foos = [Foo1, Foo2]

for i in range(2):
    print(Foos[i].__name__)
    f = Foos[i]()
    print(f.bar(10))

Traceback (most recent call last):
  File "python", line 47, in <module>
  File "python", line 13, in __call__
TypeError: bar() missing 1 required positional argument: 'x'

Isso foi testado no python 2.7 e 3.5.

Qualquer ajuda é apreciada. Observe que eu já pesquisei completamente a web inteira e já li os seguintes artigos sobre o assunto:

Graham Dumpleton: Como você implementou seu decorador Python está errado.decorator pacote na documentação do PyPI

Observe também quedecorator O pacote não suporta o segundo método para incorrer em decoradores (pré-inicializando objetos do decorador) que eu saiba.

questionAnswers(1)

yourAnswerToTheQuestion