Search code examples
pythonoperator-overloadingmetaprogramming

How to define an operator for a Python class, rather than its instances


In Python, I can define the behaviour of the "plus" operator for instances of my class:

class A:
    def __add__(self, x):
        return f"adding {x}"

A() + 3 # returns "adding 3"

But how do I define an operator for my class itself? Normally I would use the @classmethod or @staticmethod decorators:

class A:
    @classmethod
    def __add__(cls, x):
        return f"adding {x} to {cls}"

print(A + 1)

But it does not work:

Traceback (most recent call last):
  File "class_operator.py", line 6, in <module>
    print(A + 1)
TypeError: unsupported operand type(s) for +: 'type' and 'int'

How can I make that code work?


Solution

  • This problem is described in Python's reference documentation here: https://docs.python.org/3/reference/datamodel.html#special-method-lookup

    Instead of using the @classmethod decorator, you have to use a metaclass:

    class A(type):
        def __add__(cls, x):
            return f"Adding {x} to {cls}"
    
    
    class B(metaclass=A):
        pass
    
    
    print(B + 1) # prints: Adding 1 to <class '__main__.B'>