Proposal to add __str__ method to iterables:
Proposed behavior of the __str__ method for iterables is that it
returns the result of "".join(str(i) for i in self).
Justification:
Notice this difference in the behavior of filter* and a list
comprehension:
>>> filter(lambda c: c!="a", "abracadbra")
'brcdbr'
>>> [c for c in "abracadbra" if c != "a"]
['b', 'r', 'c', 'd', 'b', 'r']
*This is the pre-3.0 filter's behavior. Post-3.0, "filter" is really
ifilter.
In order to replicate the behavior of filter with a comprehension, the
return type must be the same as the input type:
>>> def my_filter(cond, it):
... return type(it)(i for i in it if cond(i))
Thus, we get the same results using the old style filter and my_filter:
>>> filter(lambda c: c!="a", (1,2))
(1, 2)
>>> my_filter(lambda c: c!="a", (1,2))
(1, 2)
>>> filter(lambda c: c!="a", [1,2])
[1, 2]
>>> my_filter(lambda c: c!="a", [1,2])
[1, 2]
But not in every case!
>>> filter(lambda c: c!="a", "abracadbra")
'brcdbr'
>>> my_filter(lambda c: c!="a", "abracadbra")
'<generator object at 0x27c2300>'
Why does my_filter return a string saying "<generator object at
blah>"? Because generator objects have no __str__ method, so
str(gen_obj) returns gen_obj.__repr__().
So, my proposal is to make strings act like the other members of the
iterable family by adding an __str__ method to them, which does a
"".join on the str of its members.
- - - -
Potential downside #1: Don't try to print an infinite object, like
itertools.count().
Other potential downside #2: This makes "".join(l) obsolete.
Regarding #1: Do a repr instead.
Regarding #2: I don't consider that to be a bad thing actually. I
think doing "".join is very unnatural for people new to Python, and I
think that even as people who are used to Python, I think we should
admit that it's a little weird to join list members in that way.
In terms of actual implementation, this could also be done by having
the str class look for a __str__ method then a __iter__ method and
only then use __repr__ as the final fallback instead of falling back
to __repr__ as is done now. That might be easier than adding __str__
methods to all iterables.
- - - -
Incidentally, I think the idea that str(["1", "2"]) should return "[1,
2]" is a terrible idea. Where's the use case for that? When would you
ever need to print that? It should return "12", which actually does
have a use case as the replacement for "".join(["1", "2"]).
_______________________________________________
Python-3000 mailing list
Python-3000@python.org
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe:
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com