[Python-ideas] Suggested MapView object (Re: __len__() for map())
Steven D'Aprano
steve at pearwood.info
Thu Dec 13 06:08:19 EST 2018
On Thu, Dec 13, 2018 at 06:53:54PM +1300, Greg Ewing wrote:
> In any case, I don't claim that my MapView implements the full
> iterator protocol, only enough of it to pass for an iterator in
> most likely scenarios that assume one.
Whether your hybrid sequence+iterator is close enough to an iterator or
not isn't the critical point here. If we really wanted to, we could
break backwards compatibility, with or without a future import or a
deprecation period, and simply declare that this is how map() will work
in the future. Doing that, or not, becomes a question of whether the
gain is worth the breakages.
The critical question here is whether a builtin ought to include the
landmines your hybrid class does. *By design*, your class will blow up
in people's faces if they try to use the full API offered. It violates
at least two expected properties:
- As an iterator, it is officially "broken" because in at least two
reasonable scenarios, it automatically resets after being exhausted.
(Although presumably we could fix that with an "is_exhausted" flag.)
- As a sequence, it violates the expectation that if an object is
Sized (it has a __len__ method) calling len() on it should not
raise TypeError;
As a sequence, it is fragile and easily breakable, changing from a
sequence to a (pseudo-)iterator whether the caller wants it to or not.
Third-party code could easily flip the switch, leading to obscure
errors.
That second one is critical to your "Do What I Mean" design; the whole
point of your class is for the object to automagically swap from
behaving like a sequence to behaving like an iterator according to how
it is used. Rather than expecting the user to make an explicit choice of
which behaviour they want:
- use map() to get current iterator behaviour;
- use mapview() to get lazy-sequence behaviour;
your class tries to do both, and then guesses what the user wants
depending on how the map object happens to get used.
--
Steve
More information about the Python-ideas
mailing list