Can __iter__ be used as a classmethod?

Alex Martelli aleax at aleax.it
Thu Mar 6 06:19:32 EST 2003


Michele Simionato wrote:
   ...
> True, but my point was that this very little convenience does not
> justify (IMHO) the introduction of classmethods in the language.
> There are two typical cases:
> 
> 1) I want to be able to call A().f(). Then I can use a regular method
> defined in A and inside the method I extract the class with type(self);
> 
> 2) A is not meant to be instantiated, and I want to use the notation
> A.f(). Then I can define a regular method in the metaclass.

Actually, a very typical use case for class methods (in Smalltalk at
least) is for *factories* -- which of course are only useful for
classes that ARE meant to be instantiated, because they typically
return class instances.


> Then, there is a limit case, where f is defined in the metaclass of A,
> but I want to call it from an instance of A. In this case it is enough
> to write type(A()).f().

But with classmethods, client code doesn't NEED to know what is defined
where, and that is an IMPORTANT advantage.

> Therefore in any case, simply by typing few characters more, I can emulate
> the classmethod effect (if not the precise syntax and some subtility).

And not the smooth polymorphism -- an important issue.

You've already said you do see the usefulness of static methods.  OK,
great, so assume static methods ARE in the language -- somebody writes
a nice package where you can call factories as a = A.fact(1,2,3) AND
also later b = a.fact(4,5,6) and live happily... *AS LONG AS* the
factory doesn't need to know exactly what class it's being called on,
for example because A is not designed to be subclasses, and say that's
the case initially.  You write client code blissfully unaware, not
NEEDING to be aware, that A.fact is a static method, and of whether
some instances of A may override that method in certain cases -- all
is good in the world.

But now, second release of the same package, it turns out that in
some cases it IS important to know exactly on what class the method
is being called on -- because now you're allowed to subclass A, by
design, and after "class B(A): pass" you get the certainty that
b = B.fact(1,2,3) will generate an instance of B and so later will
b.fact(1,2,3).  Pretty common case, by the way, at least if you
have any Smalltalk experience/background.

With classmethods, no problem at all.  Without them, not a good place
to be in -- each author of a package in such a situation would need
to perform rather complicated metaclass magic to inject 'fact' in
the metaclass AND in every instance too... or else reimplement
classmethods, which is what sensible ones would do.  Over and over
and over again.

And that's the argument FOR classmethods -- avoiding multiple and
redundant reimplementations of the same useful design pattern.  What's
so problematic with it for you?  Just the fact that you're not
familiar with it?  I can see no other reason you'd like *static*
methods but dislike *class* ones, except familiarity!


> If Python had no metaclasses, I would think classmethods are useful; but
> since Python has metaclasses, I think they are redundant and a possible
> source of confusion.

So shall we abrogate unary minus and force everybody to code 0-x
where they'd now code -x?  Unary minus is also "redundant and a possible
source of confusion" -=- I've lost count of how many times I've had
to explain to puzzled beginners why -2**2 is -4 (a wart, IMHO)...


Alex





More information about the Python-list mailing list