Are decorators really that different from metaclasses...

Paul Morrow pm_mon at yahoo.com
Mon Aug 30 18:22:04 EDT 2004


Hallvard B Furuseth wrote:

> Paul Morrow wrote:
> 
>>I believe that we should think of assignments to __xxx__ attributes as 
>>not being part of the function's body, but instead part of its 
>>declaration, just as we do with its docstring.
>>
>>    def circum(diameter):
>>        """This describe's foo."""
>>        __author__ = 'Paul Morrow'
>>        __version__ = '0.1'
>>        __features__ = synchronized, memoized
> 
> 
> I really, really don't like this idea.  Assignment in Python has quite
> enough pitfalls already.  Please don't make it worse.  If it looks like
> an assignment to a local variable, it should be an assignment to a local
> variable.  

Actually, these look like assignments to local *magic* variables.
There's the difference.  The double underscores before and after each
name loudly proclaims that these variables are not like 'normal'
variables.  They're special in some way.  That's a Python convention.


> If we are going to invent a syntax for declaring function
> attributes inside the function, why confuse the issue by making it look
> like it does something else?
> 

Because 1) adding new syntax should be resisted as much as possible
(IMO), and 2) this style has parallels in both class definitions and 
module definitions.  Compare this class statement with the function def 
above.

     class Oval(Circle):
         """This describe's Oval."""
         __author__ = 'Paul Morrow'
         __version__ = '0.1'
         __metaclass__ = M


> It's true that it makes it look more like what __*__ attribute
> assignment in class bodies does, but the simple fact is that class
> bodies are executed when the class statement is executed, and function
> bodies are not executed when the def statement is executed.  Now you
> want part of the function bodies to be executed at def time, and part at
> call time.
> 

Maybe we just need to be clear as to which lines under the def statement
constitute the function's /body/.  The function's docstring gets
assigned during processing of the def statement, therefore the docstring
is apparently not part of the function body; I think of it as part of
the function's declaration.  So why not have assignments to __xxx__
variables also be part of the function's declaration.  The distinctive
appearance of these names helps remind us that they have special semantics.

And note that if __xxx__ variables/attributes inside of function defs 
*don't* have special semantics (i.e. if they are being used as normal 
local variables), then they are improperly named (in accordance with our 
naming conventions).

> __*__ assigments in class bodies can look a little confusing if you
> don't think of how class declarations work, but it's perfectly simple
> once you think of how they do work: Execute the class body - no magic
> involved (as far as I know).  Then pass the resulting __dict__ to the
> class creation machine - and _that_ recognizes __metaclass__, __slots__
> and I don't know what else and does magic with them.
> 
> Once you remember that, __*__ variables in both class bodies and
> function bodies do exactly what one would expect them to do.  Stronger
> magic, like grabbing the doc string and putting it in __doc__, has its
> own syntax.
> 

Perhaps its just my experience with declarative programming languages,
but I prefer thinking of __xxx__ assignments in a class as setting
'properties' of the class.  It's a higher level of abstraction than
thinking in terms of the procedural mechanics of what happens under the
hood.  And the syntax used to set properties in classes/modules should 
be the same one used to set properties in functions and methods (IMO).

Paul







More information about the Python-list mailing list