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?
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.