Are decorators really that different from metaclasses...

Paul Morrow pm_mon at yahoo.com
Fri Aug 27 07:41:14 EDT 2004


Andrew Durdin wrote:
> On Thu, 26 Aug 2004 20:54:22 -0400, Paul Morrow <pm_mon at yahoo.com> wrote:
> 
>>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.
> 
> 
> That's because the dictionary interface/protocol requires a
> __getitem__ method; there's no magical/technical reason why it should
> be called __getitem__ rather than, say,  dict_get_item.

Um.  Actually there is a reason why __getitem__ should be named 
something that starts and ends with double underscores.  It's magical. 
By defining that method, instances of your class have special behavior. 
  The *convention* is to surround magic methods with double underscores. 
  So no, dict_get_item would not be a proper substitute name.

> As an example, the iterator protocol requires two methods: __iter__()
> and next() -- the second doesn't have the double underscores

Ok I'll just say it (ban me from the newsgroup if this stings too much). 
  The 'next' method is poorly named.  It doesn't follow conventions for 
magic methods.  It should be fixed.  It should be __next__

> 
>  All the "magic"
> __X__ methods are just those methods required by certain built-in
> interfaces/protocols. And there's syntactic sugar to make them
> convenient. They don't affect the creation of the class at all, as you
> can (if necessary) add them in after the fact:
> 

Of course you can.  In fact, you could do all of your programming that 
way, where you create an empty class, then add the methods and 
attributes after the fact.  Even more fun would be to not even 
explicitly create the class (with a class statement), but instead call a 
function that returns an empty class, and then add your attributes to 
the function result.

But that's not a very effective way to program if you care about program 
maintenance.  As a reader of your code, I'll have a much harder time 
understanding what you're doing than if you adhered to basic conventions 
(like defining all of your methods and attributes inside of a class 
statement).

But my point was that the presence of certain magic methods/attributes 
'says' [*] something to the reader about our code.

Paul

* implicitly 'declares'.




More information about the Python-list mailing list