__metaclass__ and __author__ are already decorators

Paul Morrow pm_mon at yahoo.com
Sat Aug 21 11:57:54 EDT 2004


Andrew Durdin wrote:

> On Sat, 21 Aug 2004 10:38:01 -0400, Paul Morrow <pm_mon at yahoo.com> wrote:
> 
>>Thinking about decorators, and looking at what we are already doing in
>>our Python code, it seems that __metaclass__, __author__, __version__,
>>etc. are all examples of decorators.  So we already have a decorator
>>syntax.  What is the compelling reason to invent a new one?  And if we
>>do, what's to become of the old one?
> 
> 
> __author__ and __version in a class (as per your example) are setting
> class attributes, not "decorating" the class anymore than the def's
> that declare instance methods are.
> Within a function, __author__ and __version__ are local variables, and
> nothing more; specifically, assigning to them does *not* set function
> attributes:
> 
>   >>> def foo():
>   ...     __author__ = "me"
>   ...     return 5
>   ...
>   >>> print foo.__author__
>   Traceback (most recent call last):
>     File "<stdin>", line 1, in ?
>   AttributeError: 'function' object has no attribute '__author__'
>   >>> print foo.func_code.co_varnames
>   ('__author__',)
> 

That's right.  But we don't *use* __author__, __version__, etc. as class 
attributes --- we use them to supply metadata for the class.  By that I 
mean that we don't intend for those attributes to be referenced by any 
methods of the class or users of the class.  Those attributes are there 
strictly to supply information about the class.  To 'decorate' the class.

So the Python system will have to be changed to support this new way of 
thinking about __xxx__ attributes.  They should no longer appear as 
local variables of a class or method, but instead as (meta) attributes 
of the class or method itself.  So in your example

     def foo():
         __author__ = "me"
         return 5

would be the same as

     def foo():
         return 5

     foo.__author__ = "me"



> __metaclass__ on the other hand is a magic attribute. I haven't worked
> out the details, but I have the feeling that what a metaclass does to
> a class is not replicable merely by decorating the class; in other
> words, that:
> 
>   class Foo:
>       __metaclass__ = Bar
> 
> is *not* equivalent to
> 
>   class Foo:
>       pass
> 
>   Foo = Baz(Foo)
> 
> for any definitions of Bar and Baz. This is just my intuition, however.

Well, although it amounts to roughly the same thing

     class Foo:
         __metaclass__ = Bar

would actually equate to either

     class Foo:
         pass

     Foo = metaclass(Foo, Bar)

or

     class Foo:
         pass

     metaclass(Foo, Bar)

depending on whether we decide that decorator functions should return 
new classes/functions (treating the decorated class/function as 
immutable), or allow them to modify the decorated function in place, in 
which case I guess they'd return None.

Either way, I *can* imagine a definition of metaclass that could 
properly make Bar the metaclass of Foo.





More information about the Python-list mailing list