Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Are decorators really that different from metaclasses...

Reply
Thread Tools

Re: Are decorators really that different from metaclasses...

 
 
Paul Morrow
Guest
Posts: n/a
 
      08-25-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/...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

 
Reply With Quote
 
 
 
 
Jess Austin
Guest
Posts: n/a
 
      08-25-2004
Paul Morrow <> wrote in message news:<mailman.2346.1093432824.5135.python->...
>
> 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:


Here I think you're making an unwarranted assumption. There is
currently nothing stopping an object from using information about
itself to do its job. And this is sometimes a useful freedom. As an
example, you might have subclasses whose only real purpose is to keep
track of their class and metadata, and have all functionality provided
by their superclass:

class supe(object):
"""this docstring is rarely frobnosticated"""
def do_something_based_on_metadata():
frobnosticate(self.__doc__)

class sub1(supe):
"""I am sub1"""

class sub2(supe):
"""I am sub2"""

Something like this could often be considered premature
objectification, but I've used it successfully. Also, you'll notice
that these are classes rather than simple functions - I admit I've
never had a need to think about function metadata before.

However, I know that many people have a specific view of metadata and
don't really see how decorators fit in. To be frank, I think pep318
shoehorned in metadata to pretend that there was a wider application
area for decoration than there really is. The current quite minimal
support for metadata is sufficient for 99% of metadata use cases. My
example has worked in Python for some time. I know that decorators
would allow different behaviors to be arbitrarily assigned to various
pieces of metadata, but that doesn't seem like a big win for code
maintainability. If anyone decided to support pep318 based solely on
a love of metadata, he made a mistake.

I'm intrigued by decorators anyway, and in no small part because it
seems that they should be able to completely replace metaclasses,
which are themselves totally unrelated to metadata. In fact, that's
what at first prompted me to read a thread with the title, "Are
decorators really that different from metaclasses..." Class
decorators wouldn't be so different from metaclasses, but J2 or even
@pie are much better syntaxes than the current metaclass syntax.

In another post in this thread Anthony Baxter said they were
different. I'll respond directly to that post.

later,
Jess
 
Reply With Quote
 
 
 
 
Paul Morrow
Guest
Posts: n/a
 
      08-25-2004
Jess Austin wrote:
>
> Here I think you're making an unwarranted assumption. There is
> currently nothing stopping an object from using information about
> itself to do its job. And this is sometimes a useful freedom. As an
> example, you might have subclasses whose only real purpose is to keep
> track of their class and metadata, and have all functionality provided
> by their superclass:
>
> class supe(object):
> """this docstring is rarely frobnosticated"""
> def do_something_based_on_metadata():
> frobnosticate(self.__doc__)
>
> class sub1(supe):
> """I am sub1"""
>
> class sub2(supe):
> """I am sub2"""
>


What you're trying to illustrate (I believe) is a superclass doing
something based on the docstring of a subclass. Yes this certainly does
happen. But the superclass and subclass are separate objects. I was
talking about the situation where a function does something based on
/its own/ metadata. That is what I'm saying virtually never happens,
and therefore it's ok to make all assignments to __xxx__ attributes
inside of a function def create /function attributes/ rather than /local
variables/.


Paul

 
Reply With Quote
 
Paul Morrow
Guest
Posts: n/a
 
      08-25-2004
Paul Morrow wrote:

> and therefore it's ok to make all assignments to __xxx__ attributes
> inside of a function def create /function attributes/ rather than /local
> variables/.


In My Opinion.


 
Reply With Quote
 
Anthony Baxter
Guest
Posts: n/a
 
      08-26-2004
On Wed, 25 Aug 2004 19:47:35 -0400, Paul Morrow <> wrote:
> What you're trying to illustrate (I believe) is a superclass doing
> something based on the docstring of a subclass. Yes this certainly does
> happen. But the superclass and subclass are separate objects. I was
> talking about the situation where a function does something based on
> /its own/ metadata. That is what I'm saying virtually never happens,
> and therefore it's ok to make all assignments to __xxx__ attributes
> inside of a function def create /function attributes/ rather than /local
> variables/.


This is an extraordinarily complex idea - you're proposing that inside
a function there is now access to a brand new namespace, that of the
function object itself. I don't think you appreciate just _how_ much
work this would requre, nor the complexity of trying to explain this
to users. Remember, at the moment, you can't even get access to the
function object itself from inside the function, without using a hack
like sys._getframe() or raising an exception.

Putting aside nested scopes for the moment, there are three namespaces
that are used in Python - local, module level global, and builtins.
You're proposing that there is a new namespace, that of the function
object, and that it only be used by accessing any local variable that
starts or ends with two underscores. At the moment, the scoping rules
for Python are _extremely_ simple. Do you really want to add something
like this, that looks like a hack, smells like a hack, and who's
implementation would be a hack? I know I don't want to see something
like this.
 
Reply With Quote
 
Paolo Veronelli
Guest
Posts: n/a
 
      08-26-2004


Anthony Baxter wrote:
> On Wed, 25 Aug 2004 19:47:35 -0400, Paul Morrow <> wrote:
>
>>What you're trying to illustrate (I believe) is a superclass doing
>>something based on the docstring of a subclass. Yes this certainly does
>>happen. But the superclass and subclass are separate objects. I was
>>talking about the situation where a function does something based on
>>/its own/ metadata. That is what I'm saying virtually never happens,
>>and therefore it's ok to make all assignments to __xxx__ attributes
>>inside of a function def create /function attributes/ rather than /local
>>variables/.

>
>
> This is an extraordinarily complex idea - you're proposing that inside
> a function there is now access to a brand new namespace, that of the
> function object itself. I don't think you appreciate just _how_ much
> work this would requre, nor the complexity of trying to explain this
> to users. Remember, at the moment, you can't even get access to the
> function object itself from inside the function, without using a hack
> like sys._getframe() or raising an exception.


It's not the ideas complexity that fears,but the feeling we are trying
to bring down to earth the supposed magic of some language solutions.
There is nothing good in magic,specially when you have to build robust
things on it.


> Putting aside nested scopes for the moment, there are three namespaces
> that are used in Python - local, module level global, and builtins.
> You're proposing that there is a new namespace, that of the function
> object, and that it only be used by accessing any local variable that
> starts or ends with two underscores. At the moment, the scoping rules
> for Python are _extremely_ simple. Do you really want to add something
> like this, that looks like a hack, smells like a hack, and who's
> implementation would be a hack? I know I don't want to see something
> like this.


If this blows away clouds on the language future and bring back the
useful features in a wider theory where metaclasses and decorators are
members of,this shouldn't be considered a hack.If it becomes a hack the
problem is to be searched and solved above generalizing the scope system.


 
Reply With Quote
 
Anthony Baxter
Guest
Posts: n/a
 
      08-26-2004
On Thu, 26 Aug 2004 10:28:14 +0200, Paolo Veronelli
<> wrote:
> It's not the ideas complexity that fears,but the feeling we are trying
> to bring down to earth the supposed magic of some language solutions.
> There is nothing good in magic,specially when you have to build robust
> things on it.


I have no idea what you're trying to say here. Are you saying that the
approach of double-under variables inside a function having some new
meaning, getting put into a new scope that did not previously exist,
is somehow _less_ magical that the syntactic sugar of decorators? If
so, how do you intend to handle the backwards compatibility issue,
where code that works on Python2.4 will do something entirely
different on Python2.3 (the double-under variables will be silently
ignored). Do you intend that the double-under names would also be
looked for in the same scopes? That is, what will this code do?

def foo():
__name__ = '%s_banana'%(__name__)

> If this blows away clouds on the language future and bring back the
> useful features in a wider theory where metaclasses and decorators are
> members of,this shouldn't be considered a hack.If it becomes a hack the
> problem is to be searched and solved above generalizing the scope system.


Hand waving is all well and good, but this isn't a matter of
"generalizing the scope system". This is a _radical_ change to the
scoping rules of Python, and I think it's safe to say that there's
*absolutely* *no* *way* something like this would be considered,
without an excellent reason - and bolting some sort of strange
decorator semantics doesn't cut it.

Anthony
 
Reply With Quote
 
Paul Morrow
Guest
Posts: n/a
 
      08-26-2004
Anthony Baxter wrote:
> On Wed, 25 Aug 2004 19:47:35 -0400, Paul Morrow <> wrote:
>
>>What you're trying to illustrate (I believe) is a superclass doing
>>something based on the docstring of a subclass. Yes this certainly does
>>happen. But the superclass and subclass are separate objects. I was
>>talking about the situation where a function does something based on
>>/its own/ metadata. That is what I'm saying virtually never happens,
>>and therefore it's ok to make all assignments to __xxx__ attributes
>>inside of a function def create /function attributes/ rather than /local
>>variables/.

>
>
> This is an extraordinarily complex idea - you're proposing that inside
> a function there is now access to a brand new namespace, that of the
> function object itself. I don't think you appreciate just _how_ much
> work this would requre, nor the complexity of trying to explain this
> to users. Remember, at the moment, you can't even get access to the
> function object itself from inside the function, without using a hack
> like sys._getframe() or raising an exception.
>


No I'm not suggesting that. The function would continue to have exactly
the same namespace.

This is not a big change; quite the contrary...

The interpreter, when it is executing a def statement, after it binds
__doc__ to the docstring, would execute any assignments to __xxx__
attributes it finds immediately following the docstring (if present). So

def circumference(diameter):
""" This is a docstring. """
__author__ = 'Paul Morrow'
pi = 3.14
return pi * diameter

would be /exactly equivalent/ to

def circumference(diameter):
pi = 3.14
return pi * diameter

circumference.__doc__ = """ This is a docstring. """
circumference.__author__ = 'Paul Morrow'


See how simple? In fact, isn't this just as simple --- or even simpler
-- than what would be require to implement J2 or A1?

And remember, the assumption here is that these assignments (to __xxx__
attributes) are a form of declarations /about the function/, just as
docstrings are now. There's no need to support conditional declarations...

def foo():
""" I am a docstring. """
__author__ = 'Morrow'

# Just as there is no proper, 'definition time' way to
# conditionally change a docstring, the code below
# will generate an exception (at runtime).
if 1:
__version__ = '0.1'
else:
__version__ = '0.2'

Think of what I'm proposing here as just a convenience syntax. We can
already do the same thing after (outsidef of) the function def as the
second circumference example above shows.

Paul

 
Reply With Quote
 
Paul Morrow
Guest
Posts: n/a
 
      08-26-2004
Anthony Baxter wrote:
> On Thu, 26 Aug 2004 10:28:14 +0200, Paolo Veronelli
> <> wrote:
>
> ignored). Do you intend that the double-under names would also be
> looked for in the same scopes? That is, what will this code do?
>
> def foo():
> __name__ = '%s_banana'%(__name__)
>


/exactly/ the same thing as

def foo(): pass

foo.__name__ = '%s_banana'%(foo.__name__)


Paul

 
Reply With Quote
 
Arthur
Guest
Posts: n/a
 
      08-26-2004
On Thu, 26 Aug 2004 17:31:16 +1000, Anthony Baxter
<> wrote:

>On Wed, 25 Aug 2004 19:47:35 -0400, Paul Morrow <> wrote:
>> What you're trying to illustrate (I believe) is a superclass doing
>> something based on the docstring of a subclass. Yes this certainly does
>> happen. But the superclass and subclass are separate objects. I was
>> talking about the situation where a function does something based on
>> /its own/ metadata. That is what I'm saying virtually never happens,
>> and therefore it's ok to make all assignments to __xxx__ attributes
>> inside of a function def create /function attributes/ rather than /local
>> variables/.

>
>This is an extraordinarily complex idea - you're proposing that inside
>a function there is now access to a brand new namespace, that of the
>function object itself. I don't think you appreciate just _how_ much
>work this would requre, nor the complexity of trying to explain this
>to users. Remember, at the moment, you can't even get access to the
>function object itself from inside the function, without using a hack
>like sys._getframe() or raising an exception.
>
>Putting aside nested scopes for the moment, there are three namespaces
>that are used in Python - local, module level global, and builtins.
>You're proposing that there is a new namespace, that of the function
>object, and that it only be used by accessing any local variable that
>starts or ends with two underscores. At the moment, the scoping rules
>for Python are _extremely_ simple. Do you really want to add something
>like this, that looks like a hack, smells like a hack, and who's
>implementation would be a hack? I know I don't want to see something
>like this.



Though I am learning stuff by trying to keep up with this conversation
- I should probably stay out of it, directly.

But, as I publically demonstrated in my confusion about __name__

....to someone educated from within Python, mostly by chucking out
code, rather than reading documentation - that __name__ accessed
from within the function body is something totally different from
__name__ accessed from outside of it, was not what I think the
language taught me to expect. I might have intuited that to expect
otherwise would be "magic", but thought, somehow, that the __xxx__
implied the availability of that kind of magic.

In other words, it would have surprised me less to have been right
than to have benn wrong.

Though I have learned not to be shocked about being wrong

And can understand the possiblity that others with other backgrounds
might be surprised if I had been right.

Does

"""
Namespaces are one honking great idea -- let's do more of those!
"""

come into play here at all?

Art

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
Re: Are decorators really that different from metaclasses... Anthony Baxter Python 3 08-26-2004 09:55 PM
Are decorators really that different from metaclasses... Paul Morrow Python 2 08-24-2004 08:14 PM
PEP 318 decorators are not Decorators Arien Malec Python 11 08-16-2004 06:38 PM
And now to sth. completely different: Forget about decorators,think cgi.FieldStorage Ames Andreas (MPA/DF) Python 0 08-05-2004 04:48 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57