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

Reply via email to