Are decorators really that different from metaclasses...
Paul Morrow
pm_mon at yahoo.com
Wed Aug 25 07:20:17 EDT 2004
Steven Bethard wrote:
> Paul Morrow <pm_mon <at> yahoo.com> writes:
>
>>I believe that (virtually) all __xxx__ attributes have this metadata
>>aspect (semantics) to them. When a programmer says
>>
>> def foo():
>> __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.
>
>
> I assume you mean that this is what you'd like a programmer to intend? If I
> wrote that, I would intend (and expect) __author__ to be a local variable.
> I'm not saying that I couldn't be retrained. I'm just saying that right now,
> I would not expect it to be otherwise.
>
What I mean is that this is what (I believe) veteran Python programmers
always intend, because it's a Python convention (although I've never
actually seen it described quite like this --- as metadata).
Here's what PEP 8 (http://www.python.org/peps/pep-0008.html) has to say
about __xxx__ attributes:
__double_leading_and_trailing_underscore__: "magic" objects or
attributes that live in user-controlled namespaces,
e.g. __init__, __import__ or __file__. Sometimes these are
defined by the user to trigger certain magic behavior
(e.g. operator overloading); sometimes these are inserted by the
infrastructure for its own use or for debugging purposes. Since
the infrastructure (loosely defined as the Python interpreter
and the standard library) may decide to grow its list of magic
attributes in future versions, user code should generally
refrain from using this convention for its own use. User code
that aspires to become part of the infrastructure could combine
this with a short prefix inside the underscores,
e.g. __bobo_magic_attr__.
Here's a link that gives some examples of them:
http://cardboard.nu/blog/2003_09_18/module_level_magic_variables.html)
Sure veterans know that if it looks like a local variable definition,
then it is one. But my point is that (IMO) they don't normally rely on
that aspect of __xxx__ variables. You'll almost never see a function
that examines its own metadata in the computation of its result.
>
>>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.
>
>
> This seems a little misleading to me. The only reason these methods are
> special is because they override operators (something like "<", "[]", and "()"
> respectively). You could provide a class with /exactly/ the same
> functionality without ever implementing any of these methods. (Well, minus
> __init__, but that was a special case in your discussion too.) The only thing
> that implementing these methods does is allows your user to access these
> methods through an operator shorthand. A simple example:
>
> class Identity:
> def get(self, x):
> return x
> __getitem__ = get
>
> How is __getitem__ any more "metadata" then get is? They provide exactly the
> same functionality. The __getitem__ declaration just allows you to access the
> get method using "[...]".
>
Well, but that's a big difference. __getitem__ has a much deeper
meaning than your 'get'. Defining it actually changes which syntax
you're allowed to use on instances of your class. Now you can do things
like...
ident = Identity()
print "%(alpha)s, %(beta)s, %(gamma)s" % ident
> Are you trying to say that "metadata" is the same thing as "operator shortcut"?
>
Not exactly, but it would include defining those. One way to think
about metadata is that it includes all information *about* an object,
but no information *used by* the object.
If we were to have a conversation about this conversation, then we would
be having a "meta-conversation." /metadata/ is data that describes
data. metadata for a function would be data that describes the
function; data *about* the function as opposed to data *used by* the
function. For example:
def circumference(diameter):
""" This is a docstring. It's metadata for this function. """
__author__ = 'Paul Morrow' # more metadata
pi = 3.14 # not metadata
return pi * diameter
Paul
More information about the Python-list
mailing list