There are two ways to invoke decorators: 1) by passing decorator function/class
class Foo(object):
    def __init__(self):
        self.x = 1
    @foo_decorator
    def bar(self, x):
        return self.x + x
or 2) by passing return value of the decorator function/class instance.
class Foo(object):
    def __init__(self):
        self.x = 1
    @foo_decorator("args")
    def bar(self, x):
        return self.x + x
The question is: how do I get the decorator to work for both cases, given that I need to implement the decorator using class-based method?
An example of such implementation would be
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
However, testing this simple implementation using the following code yields some errors:
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'
This has been tested on both python 2.7 and 3.5.
Any help is appreciated. Note that I have already thoroughly searched the entire web, and have already read the following articles on the subject:
- Graham Dumpleton: How you implemented your Python decorator is wrong.
- decoratorpackage on PyPI documentation
Also note that decorator package does not support the second method for incurring decorators (pre-initializing decorator objects) to my knowledge.
 
    