classmethods and data model methods, implementing operands over classes or types

Question:

Here is what you would expect if you try and use the add operand over a type and int or between two type objects.

>>> class Foo:
...     pass
...
>>> class Bar:
...     pass
...
>>> Foo + 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'type' and 'int'
>>> Foo + Bar
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'type' and 'type'

What I would like to know if, is there a way to allow the support of operands between types in a kind of straight forward way.

The only work around that I can think of to implement an interface like this is to implement a class overwriting the __call__ method, so each object of that class can actually instantiate classes from other types. That way you can "mimic" the construction by doing something like this.

class TypeArithmetic:
     def __init__(self, wrap):
          self.wrap

     def __call__(self, *args, **kwargs):
         return self.wrap(*args, **kwargs)

     def __add__(self, other):
         return 1 # Calculate something here


@TypeArithmetic
class CLASS_1:
    pass

@TypeArithmetic
class CLASS_2:
    pass

CLASS_1 + CLASS_2 # according to the __add__ here, this returns 1.

More or so.

Is there a way of achieving this without the implementation of a similar decorator?

Asked By: ekiim

||

Answers:

You can use a metaclass which defines the operators on instances of itself.

class Meta(type):
    def __add__(self, other):
        return self, other

class Foo(metaclass=Meta):
    pass

print(Foo+int) # (<class '__main__.Foo'>, <class 'int'>)

How does it work? All classes are instances of a metaclass, of which type is one, and since classes are metaclass instances, metaclasses can define methods that can be called on the class, just as ordinary classes can define methods that can be called on their instances, because classes are objects in Python.

Answered By: iteratedwalls
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.