On Mon, 06 Dec 2010 22:08:33 +1100, Ben Finney wrote: > Stef Mientki <stef.mien...@gmail.com> writes: > >> I would like to know if a class definition has a decorator, > > I'm not sure what this question means. > > Applying a decorator to a class definition produces a normal class. > > Classes don't “have” decorators; classes can be returned by a decorator > function, but AFAIK the resulting class doesn't “have” the decorator in > any sense.
It seems to me that a class decorator is (usually) like a class factory, in that it returns a class; the difference being that it takes a pre- existing class as argument, and (probably) modifies it in place, rather than creates a new class from scratch. I say "usually" and "probably" because, of course, a class decorator can do *anything*. Even something pointless: >>> def decorator(cls): ... return 1 ... >>> @decorator ... class K: ... pass ... >>> K 1 >> is that possible ? > > The return value of a decorator isn't special in any way, AFAIK. > > Any function can return a class object or a function object, and any > function can be used as a decorator. [pedant] Any callable can be a decorator, provided it has an appropriate calling signature. But you knew that :) [/pedant] > The only thing that makes a function a decorator is how it is used in > the code; but it doesn't leave a trace that I know of. Function decorators can, because they usually wrap the input function in a closure, which is detectable: >>> def decorator(func): ... def inner(): ... return func("spam") ... return inner ... >>> >>> @decorator ... def ham(s): ... return s.upper() ... >>> ham.__closure__ (<cell at 0xb7b76cec: function object at 0xb7b7f36c>,) >>> >>> def cheese(s): # no decorator ... return s.upper() ... >>> cheese.__closure__ >>> But this is only a common practice, not a guarantee, because the decorating function can do anything. I think that the only way to find out what was used to decorate a class, or a function, is for the decorator itself to leave some sort of mark on the wrapped class/function. Perhaps by adding itself to the wrapped object as an attribute: def decorate(cls): cls._decorated_by = decorate -- Steven -- http://mail.python.org/mailman/listinfo/python-list