20

How to concatenate Object with a string (primitive) without overloading and explicit type cast (str())?

class Foo:
    def __init__(self, text):
        self.text = text

    def __str__(self):
        return self.text


_string = Foo('text') + 'string'

Output:

Traceback (most recent call last):
  File "test.py", line 10, in <module>
      _string = Foo('text') + 'string'

TypeError: unsupported operand type(s) for +: 'type' and 'str'

operator + must be overloaded? Is there other ways (just wondering)?

PS: I know about overloading operators and type casting (like str(Foo('text')))

6
  • What is your expected result in _string? "textstring" ? Commented Feb 16, 2012 at 16:06
  • 3
    Why don't you want to use str to force the object into a string? Commented Feb 16, 2012 at 16:09
  • 1
    Python doesn't have casting. When you call str, you create a new string object by the return value of MyType.__str__. Casting is taking the same data in memory and telling the compiler/interpreter that it is another object type. Commented Feb 16, 2012 at 16:17
  • 1
    I'm just curious why __ str__ doesn't return the string? Commented Feb 16, 2012 at 16:18
  • 1
    __str__ does return the string. But it isn't called when + is used, because python doesn't know what + means in this case. You have to tell it explicitly. Commented Feb 16, 2012 at 16:21

3 Answers 3

26

Just define the __add__() and __radd__() methods:

class Foo:
    def __init__(self, text):
        self.text = text
    def __str__(self):
        return self.text
    def __add__(self, other):
        return str(self) + other
    def __radd__(self, other):
        return other + str(self)

They will be called depending on whether you do Foo("b") + "a" (calls __add__()) or "a" + Foo("b") (calls __radd__()).

Sign up to request clarification or add additional context in comments.

5 Comments

IMO this is not good practice. Calling str explicitly is the correct pattern. Anyway, you're still calling str here, you're just hiding it.
@Daenyth, I think it depends on the circumstances. This isn't appropriate for any old object; but for something meant to emulate a string, it's perfectly reasonable.
@Daenyth: I agree with you, but there might be exceptions.
@senderle: The first thing I'd try to emulate a string is to derive from str. Only if this is no option for some reason, I'd go with the approach above.
@SvenMarnach, yes, that's what I meant by "emulate." Perhaps I was being unclear; in my mind, a type that inherits from str is doing something more than "emulating" a string.
7
_string = Foo('text') + 'string'

The problem with this line is that Python thinks you want to add a string to an object of type Foo, not the other way around.

It would work though if you'd write:

_string = "%s%s" % (Foo('text'), 'string')

EDIT

You could try it with

_string = 'string' + Foo('text')

In this case your Foo object should be automatically casted to a string.

4 Comments

Are you sure about your edit? I'm pretty sure Python won't cast to string automatically.
@Constantinius, Thanx for the anwer, but I know about type casting. I want to understand how to return the real string from __str__
There's no such thing as Python casting objects to strings. Either the __add__ method will do it explicitly or no one will do.
I thought of '{}{}'.format(Foo('text'), 'string') first. Maybe this is also an option...
1

If that makes sense for your Foo object, you can overload the __add__ method as follows:

class Foo:
    def __init__(self, text):
        self.text = text

    def __str__(self):
        return self.text

    def __add__(self, other):
        return str(self) + other

_string = Foo('text') + 'string'
print _string

Example output:

textstring

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.