Are decorators really that different from metaclasses...
pm_mon at yahoo.com
Wed Aug 25 05:38:28 CEST 2004
Steven Bethard wrote:
> Paul Morrow <pm_mon <at> yahoo.com> writes:
>>...that they warrant an entirely new syntax?
>>So why don't they share a similar syntax?
>> class Foo:
>> """ This is the docstring for class Foo. """
>> __metaclass__ = M
>> # body of class goes here
>> def baz():
>> """ This is the docstring for function baz. """
>> __features__ = synchronized, memoized
>> # body of function goes here.
> As I'm sure someone has already mentioned, this has been brought up before.
> I'd especially look at:
Well, what I proposed there is more substantial than this, and requires
a more significant change to the Python system to accomodate.
> That being said, I think the main objection to this syntax is the same
> objection to any inside-def syntax: The code inside a funcdef block (with the
> exception of docstrings, which Guido has repeatedly said he regrets putting
> there) is executed as part of the /execution/ of the function, not
> the /definition/.
Yes, but we have the docstring precendent nonetheless. And I think that
Guido should stop regretting that decision and start recognizing the
natural beauty of it. To allow docstrings at the top of module/class
bodies, but not at the top of function/method bodies would be
asymmetrical, and we'd wonder why. Any alternative means of providing
docstrings for methods/functions would look like a wart (IMO).
Especially since the obvious place for them would still be there.
So, no, I for one like docstrings right where they are. And look at
what they create a precedent for.
When Python executes a def statement, it binds __doc__ to the docstring
it finds there. But what is __doc__? It's an attribute of the method
or function object being defined. Yep. Its metadata. It's information
*about* the method/function. __doc__ is *not* a local variable of the
method or function object being defined.
I believe that (virtually) all __xxx__ attributes have this metadata
aspect (semantics) to them. When a programmer says
__author__ = 'Wilma Flintstone'
__version__ = '0.1'
She does not intend for __author__ nor __version__ to be local variables
of foo, used somehow by foo in the calculation of its return value. To
her they are foo /metadata/ --- attributes of the foo object itself ---
as they contain information that *describes* foo.
Likewise, when she defines __lt__, __getitem__, __init__, etc. as part
of a class, they will not typically be called by methods of the class or
users/consumers/clients of the class [*] the way that 'normal'
attributes will. They contain meta info that describes a deeper level
of class behavior.
And so if all __xxx__ attributes are really metadata attributes, let's
formally recognize that. Then, when processing a function/method def,
after Python binds __doc__ to the function's docstring, it can go ahead
and bind the other __xxx__ attributes too, making them function
attributes rather than local variables. And then after it's finished
with the function def, if the function defined the __features__
attribute, Python can pass the completed function in turn to each
decorator in the __features__ tuple (or some such).
No asymmetry. No new syntax. No warts.
* well, __init__ is a little odd in this respect as subclasses will
sometimes call a parent's __init__ directly, but that's an exception.
More information about the Python-list