tags:

views:

60

answers:

3

I'm not sure what I'm doing wrong here:

>>> class Stringy(object):
...     def __str__(self):
...             return "taco"
...     def __repr__(self):
...             return "taco"
... 
>>> lunch = Stringy()
>>> lunch
taco
>>> str(lunch)
'taco'
>>> '-'.join(('carnitas',lunch))
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
TypeError: sequence item 1: expected string, Stringy found

Given my inclusion of the __str__() method in the Stringy object, shouldn't join() see lunch as a string?

+1  A: 

The call signature for str.join is:

S.join(sequence) -> string

Return a string which is the concatenation of the strings in the
sequence.  The separator between elements is S.

Notice that sequence is expected to be a sequence of strings. Lots of objects have __str__ methods, but not all of them (like Stringy) is an instance of str.

The fix, of course, is simple:

'-'.join(('carnitas',str(lunch)))
unutbu
+7  A: 

no you have to convert it to str yourself

'-'.join(('carnitas',str(lunch)))

if you have to do it for a whole sequence of items

'-'.join(str(x) for x in seq)

or

'-'.join(map(str, seq))

for your particular case you can just write

'carnitas-'+str(lunch)
gnibbler
+1 for correct answer *and* using generator expression instead of the horrible "let's create another list because we barely know list comprehension" :)
delnan
+3  A: 

''.join does not call __str__ on the items of the sequence it's joining. Every object has a __str__, after all (be it only inherited from object), therefore if join worked that way it would join up any sequence whatsoever (after stringification) -- often to weird effects. Better to have the the user call up str explicitly when warranted ("explicit is better than implicit" being one of the mottos in "The Zen of Python", after all).

You could subclass str or unicode if you want to "be" a string. Otherwise, an explicit str call will be needed to make instances of your type "become" strings.

Alex Martelli