Indeed, during the construction of the class, the class object itself is not yet built, so you cannot use it as the basis of the decorator.
One way I can think of is to not use the staticmethod decorator. Instead, internally in your own decorator, reuse the classmethod decorator. This way you guarantee that Python will at least pass in the associated class for you:
def to_class(func): """ returns a decorator aimed to force the result to be of class cls. """ def wrapper(cls, *args, **kwargs): return cls(func(*args, **kwargs)) return classmethod(wrapper)
Then use it as follows:
class TestClass(object): def __init__(self, value): self._value = (value, value) def __str__(self): return str(self._value) @to_class def test_func(value): return value
Demonstration:
>>> def to_class(func): ... """ returns a decorator ... aimed to force the result to be of class cls. """ ... def wrapper(cls, *args, **kwargs): ... return cls(func(*args, **kwargs)) ... return classmethod(wrapper) ... >>> class TestClass(object): ... def __init__(self, value): ... self._value = (value, value) ... def __str__(self): ... return str(self._value) ... @to_class ... def test_func(value): ... return value ... >>> TestClass.test_func('foo') <__main__.TestClass object at 0x102a77210> >>> print TestClass.test_func('foo') ('foo', 'foo')
The general version of your decorator is not simple; the only way around your puzzle is to use metaclassing; see my other answer , where I describe this method in more detail.
You basically need to go to the class namespace under construction, set up a temporary metaclass, and then rely on having at least one instance of the class before your decorator works; a temporary metaclass approach captures the mechanisms of creating a class to obtain the constructed class later.
Seeing that you are using this decorator as an alternative factory class, however this probably will not be ideal; if someone used your decorated functions to create instances of a class, then only the metaclass will be called too late.