Are decorators really that different from metaclasses...

Paul Morrow pm_mon at yahoo.com
Thu Aug 26 20:54:22 EDT 2004


Anthony Baxter wrote:

> On Thu, 26 Aug 2004 11:15:46 -0400, Paul Morrow <pm_mon at yahoo.com> wrote:
> 
>>__getitem__ is most certainly magical!  Defining it 'declares'
>>(implicitly, but we'll ignore that governing zen rule for the moment)
>>that instances of the containing class have dictionary semantics (that
>>they can be used, in some degree, like dictionaries).  That's magic.
>>That's meta.  That's profoundly deeper than anything defining getMonkey
>>does.
> 
> 
> What? There is *nothing* that __getitem__ "declares". __getitem__ is
> used by the interpreter.

Sure the interpreter uses __getitem__, but you use it too, right?  I 
mean, you don't need the interpreter to tell you whether instances of 
the following class can act like a dictionary, do you?

    class Foo:
       def __getitem__(self, x): pass

No you don't.  Nor do you need to pretend that you're the interpreter, 
and simulate a call to an instance of Foo.  That's because the mere 
presence of def __getitem__ tells you what you need to know.  In this 
way, __getitem__ *does* serve as a declaration (of dictionary semantics) 
[*] to you and anyone reading your code.

* But an implicit declaration of course.   I guess the only way of 
*explicitly* stating that instances of a class can act like dictionaries 
is to have the class inherit from dict or UserDict.


> used by the interpreter. When do make a call like:
> 
> someobj[key]
> 
> the interpreter turns that into 
> 
> someobj.__getitem__(key)
> 
> That's all. I can make an object that acts like a dictionary _without_
> using a __getitem__, watch:
> 
> class Foo:
>     def __init__(self):
>         self.d = dict(ape=False,spidermonkey=True)
> 
>     def getMonkey(self, key):
>         return self.d[key]
> 
>     def __getattr__(self, name):
>         if name == "__getitem__":
>             return self.getMonkey
>         else:
>             raise AttributeError, name
> 
> f = Foo()
> print f['ape']
> print f['spidermonkey']

Now hold on just a minute.  If I squint a little, I can still see 
__getitem__ in there somewhere.

Though I do believe that you are illustrating a good point; that you can 
mangle your code badly enough that it no longer lends itself to a 
declarative reading.  And then, the only way for your poor reader to 
figure out what the heck it's doing is for him/her to act like the 
interpreter and walk through your code (or run it under the debugger).
But I guess if you had a good enough reason...





More information about the Python-list mailing list