[Python-ideas] The non-obvious nature of str.join (was Re: sum(...) limitation)

Ron Adam ron3200 at gmail.com
Wed Aug 13 22:19:48 CEST 2014



On 08/13/2014 12:50 AM, Nick Coghlan wrote:
> On 13 August 2014 14:38, Stephen J. Turnbull<stephen at xemacs.org>  wrote:
>> >Wolfgang Maier writes:
>> >
>> >  > Exactly. So my point was that when you don't subclass str, but instead
>> >  > use a wrapper around it, you can give it a as str-like interface as you
>> >  > want so the thing looks and feels like a string to users, it will still
>> >  > not work as part of an iterable passed to .join
>> >
>> >You mean this behavior?
>> >
>> >wideload:~ 12:42$ python3.2
>>>>> >>>>
>> >...
>>>>> >>>>class N:
>> >...  def __init__(self, s=''):
>> >...   self.s = s
>> >...  def __str__(self):
>> >...   return self.s
>> >...
>>>>> >>>>" ".join(['a', N('b')])
>> >Traceback (most recent call last):
>> >   File "<stdin>", line 1, in <module>
>> >TypeError: sequence item 1: expected str instance, N found
>>>>> >>>>' '.join(str(x) for x in ['a', N('b')])
>> >'a b'
>>>>> >>>>
>> >
>> >Given the fact that every object is str-able, I don't think we want to
>> >give "str(x) for x in" semantics to str.join.  So I think the answer
>> >is "if you want Nasty to automatically acquire all the behaviors of
>> >str, make it a subclass of str".
> Note that this is a general problem - it is quite common to use
> explicit type checks against str rather than relying on ducktyping. In
> theory, a suitable ABC could be defined (using collections.UserString
> as a starting point), but nobody has ever found it a pressing enough
> problem to take the time to do so - it's generally easier to just
> inherit from str.

Is there a way to select a method more specifically on it's mixin?

       thing.method            # any like named method
       thing.method|mixin      # Only if it's from mixin

Where method is spelled the same on differnt types, but it's actual 
operation may be different.

Obviously that spelling won't work, but the idea is to allow a more fine 
grained method selection.

       thing.__add__|number(other)
       thing.__add__|sequence(other)
       thing.__add__|container(other)
       thing.__add__|str(other)

So if I wanted to join strings but not containers or numbers, I could use 
the __add__|str method.  And conversely if I wanted to iterate nested 
containers without iterating strings too, I could use __iter__|container 
method.


Now that I think about it a bit more, it probably would be spelled..

     mixin.method(thing, other)

But maybe for the same reason we don't normally call a class method 
directly applies?

     class.method(thing, other)


I think in most cases, the difference might be getting an attribute error 
early, vs a type error a bit later.  But it seems to me there may be other 
differences/gotcha's in the case of calling a mixin or class method directly.

Currently I'd add a type check before calling the method, but I'd like the 
finer grained method resolution over the type check.

Cheers,
    Ron



More information about the Python-ideas mailing list