Neo Neo - 4 months ago 9
Python Question

Python class decorator, cannot use constructor[SOLVED]

So I have the following decorator code


class Factory:

def __init__(self, cls):
self.cls = cls

def __instancecheck__(self, inst):
return isinstance(inst, self.cls)

def Produce(self):
return self.cls()



And the following class code


@Factory
class Foo:

def __init__(self, arg):
self.arg = arg

def method(self): pass




Which works great. Allows me to do stuff like


Foo.Produce().method()



Instead of

instance = Foo()
instance.method()


But now I cant use the class constructor normally

Foo(arg)


Gives the exception 'Factory object is not callable'. My question is the following: How can I make a decorator that allows me to instantiate the decorated class using its constructor, but also allows me to use a function in the decorator?

Alternative ways I'd rather not use:


  1. Skip the constructor. Always use
    <Class>.Produce()
    (and use
    *args
    /
    **kwargs
    to make it abstract/reusable.

  2. Use setters in all the classes, and make them return
    self
    so they can be chained.

  3. Make a class containing the produce method and extend this class.



EDIT:
Working code

class Factory:

def __init__(self, cls):
self.cls = cls

def __call__(self, *args, **kwargs):
return self.cls(*args, **kwargs)

def __instancecheck__(self, inst):
return isinstance(inst, self.cls)

def Produce(self,*args, **kwargs):
return self.cls(*args, **kwargs)

Answer

The exception is telling you all you need to know, just add a __call__ method:

class Factory:
    # ...

    def __call__(self, *args, **kwargs):
        return self.cls(*args, **kwargs)