[Python-ideas] + operator on generators
Brendan Barnwell
brenbarn at brenbarn.net
Tue Jun 27 14:17:44 EDT 2017
On 2017-06-27 00:47, David Mertz wrote:
> Maybe if you are confident a and b are exactly NumPy arrays it is
> obvious, but what about:
>
> from some_array_library import a
> from other_array_library import b
>
> What do you think `a & b` will do under your proposal? Yes, I understand
> it's deterministic... but it's far from *obvious*. This isn't even
> doing something pathological like defining both `.__iter__()` and
> `.__and__()` on the same class... which honestly, isn't even all that
> pathological; I can imagine real-world use cases.
Hmmm, is the proposal really meant to include behavior that global and
non-overridable? My understanding was that the proposal would
effectively be like defining a default __and__ (or whatever) on some
basic iterator types. Individual iterables (or iterators) could still
define their own magic methods to define their own behavior. Because of
that, I wouldn't expect it to be obvious what would happen in your case.
If I import types from two random libraries, I can't expect to know
what any operator does on them without reading their docs.
Also because of that, I think it might be a bit much to expect this new
concat operator to work on ALL iterables/iterators/ Nothing else really
works that way; types have to define their own operator behavior.
Iterators can be instances of any class that defines a __next__, so I
don't see how we could support the magic-concat-everything operator
without interfering there.
So. . . wouldn't it be somewhat more reasonable to define this concat
operator only on actual generators, and perhaps instances of the common
iterator types returned from zip, enumerate, etc.? Someone earlier in
the thread said that would be "weird" because it would be less generic
than itertools.chain, but it seems to me it would cover most of the
needed use cases (including the one that was initially given as a
motivating example). Also, this generator.__add__ could be smart about
handling other iterables on the right of the operator, so you could do
(x for x in blah) + [1, 2, 3] + "hello"
. . .and, as long as you started with a regular generator, it could
work, by having the magic method return a new instance of a type that
also has this behavior.
This would be a bit odd because I think most existing Python types
don't try to do this kind of thing (subsuming many different types of
right-operands). But I think it would be useful. In the interim, it
could be played with by just making a class that implements the __add__
(or whatever), so you could do
cool_iterator(x for x in blah) + [1, 2, 3] + "hello"
. . . and just wrapping the leftmost operand would be enough to give you
nice syntax for chaining all the rest.
--
Brendan Barnwell
"Do not follow where the path may lead. Go, instead, where there is no
path, and leave a trail."
--author unknown
More information about the Python-ideas
mailing list