some random reflections of a "Python newbie": (2) language issues

alex at magenta.com alex at magenta.com
Fri Dec 10 06:39:52 EST 1999


In article <001e01bf42bd$4da0cfe0$60a2143f at tim>,
  "Tim Peters" <tim_one at email.msn.com> wrote:
> [Alex Martelli]
> > ...
> > 4. why can't I overload "in" to have the
> >     expected semantics and maybe be fast...?
> >
> > "if a in X:" and "for a in X:" will now both
> > give errors unless X is a sequence.
>
> "for a in X:" also works fine if X is an instance of a class that
> supports the special __getitem__ method; see the docs;

Doesn't __len__ need to be implemented, too?  OK, I had
mis-read the docs, sorry.  I thought both __getitem__ and
__len__ needed to be implemented, so a potentially unbound
"stream" thingy couldn't really support "for a in X:"...
Python's reality is indeed better than that!-)


> you are not required to look at __getitem__'s index argument, and,

The only problem with not looking at __getitem__'s "key"
parameter seems to be that there is no way to "restart
from the beginning" -- but I guess one could easily
special-case-interpret a key of 0 to mean that.  E.g.:

class fib:
    "Enumerate the rabbits of a guy from Pisa"
    def __init__(self):
        (self.old, self.lat) = (0, 1)
    def __getitem__(self, key):
        if key==0:
            self.__init__()
            return self.old
        new = self.old+self.lat
        (self.old, self.lat) = (self.lat, new)
        return self.old

Now,
>>> rabbits=fib.fib()
>>> for i in rabbits:
... 	if i>100: break
... 	print i
does work as I thought it should.

Sigh -- but, this language _is_ cool...!-)

If an object, like this "rabbits", "is-an" enumerator (in
the sense I think of as "being an enumerator":-), things
are, indeed, fine.

However, there is one little problem remaining... being
an enumerator doesn't let the object support nested loops
on itself, which a "real" sequence has no problems with.
If the object "can give out an enumerator" to itself,
rather than keeping state itself for the enumeration,
it would be more general/cleaner.

I guess I can live with that through an "enumerator" func,
somewhat like (if I define __enumerator__ to be the
"give-out-an-enumerator" method):

def enumerate(obj):
    try:
        return obj.__enumerator__()
    except:
        try:
            return obj[:]
        except:
	    return obj

(not ideal, sure -- I actually want to give out the obj
if it's an immutable sequence [can I rely on its having
__hash__ for that...?], slice it if it's a mutable one,
etc, but, basically...), so I can have a loop such as
"for x in enumerate(whatever):" which _is_ polymorphic
_and_ nestable.

_WAY_ cool...!!!

Btw, a request for stylistic advice -- am I overusing
try/except in the above sketch for "enumerate"?  Python
seems to make it so easy and elegant to apply the good
old "easier to ask for forgiveness than permission" idea,
that my C++-programmer-instincts of only using exceptions
in truly exceptional cases are eroding fast -- yet I see
that recommendation in Guido's own book (p. 192 -- soon
belied by the example on p. 194 that shows exceptions
used to implement an anything-but-exceptional typeswitch,
but...).  Maybe in a smoothly dynamic language such as
Python keeping "exception purity" is not such a high
priority as in C++ or Java...?

How would/should I implement "enumerate" without so much
reliance on try/except, i.e. by explicitly testing "does
this object have an __enumerator__ method that can be
called without arguments, or, if not, can I slice it to
get a copy, or, ...", etc...?  In C++ I guess I'd do a
dynamic_cast<> for this kind of thing (assuming inheritance
from suitable abstract classes) -- what's the "best"
Python idioms, and what are the trade-offs here...?


> "if a in X:" currently works only if X is a list, tuple or string.  In
> Python 1.6 it's supposed to work too if X is an instance of a class
> that supports the special __contains__ method; see the 1.6 docs,

Oh my -- I even guessed the *name* of the special method
needed...?!-)  That cuts it, I guess -- Python and I were
just _made_ for each other!-).

My US$50 are on their way, despite the parlous situation
of the Euro vis a vis the dollar...!-)


Alex-the-Python-newbie


Sent via Deja.com http://www.deja.com/
Before you buy.



More information about the Python-list mailing list