Search code examples
pythonpython-3.xconcatenationstring-concatenation

Support string concatenation when using the Str classes' dunder method


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.


Solution

  • 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)