Support string concatenation when using the Str classes' dunder method

Question:

Consider a class which supports cast to string, and supports concatenation (Python add) when the second operand is a string:

$ cat dunder.py    
class Foo:

    def __str__(self):
        return "foo"

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

f = Foo()
print(f)
print(f + "bar")
print("bar" + f)

The print(f) and print(f + "bar") methods are output to the screen as expected. However, the print("bar" + f) method throws an exception as expected:

$ python3 dunder.py 
foo
foobar
Traceback (most recent call last):
  File "dunder.py", line 12, in <module>
    print("bar" + f)
TypeError: can only concatenate str (not "Foo") to str

How can I modify the class to support string concatenation when it is the str classes’ dunder method performing the concatenation?

Note that I do not want to extend the str class, I am interested in the general case.

Asked By: dotancohen

||

Answers:

You need to implement __radd__ method, which is a right sided add, used as a fallback when standard __add__ fails. It gets called on the right object in the add operation, with left object being its other parameter, so you need to perform the concatenation in a reverse order.

class Foo:

    def __str__(self):
        return "foo"

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

    def __radd__(self, second):
        return str(second) + str(self)

f = Foo()
print(f)
print(f + "bar")
print("bar" + f)
Answered By: matszwecja