[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