Dividing a number by instances of my class in Python
The __rtruediv__
method is what you're looking for.When x / y
is executed, if type(x)
does not implement a __div__(self, other)
method where other
can be of class type(y)
, then type(y).__rtruediv__(y, x)
is executed, and its result is returned.
Usage:
class Foo: def __init__(self, x): self.x = x def __truediv__(self, other): return self.x / other def __rtruediv__(self, other): return other / self.x
>>> f = Foo(10) >>> f / 101.0>>> 10 / f1.0
Yes. You just have to make sure that Time.__rtruediv__()
returns a Frequency
instance when it receives a float or integer.
Usage:
>>> 100 / Time(2)Frequency(50.0)>>> 2.5 / Time(5)Frequency(0.5)
Implementation:
class Time: def __init__(self, value): self.value = value def __rtruediv__(self, other): if not isinstance(other, (int, float)): return NotImplemented return Frequency(other / self.value)class Frequency: def __init__(self, value): self.value = value def __repr__(self): return '{}({})'.format(self.__class__.__name__, self.value)
The python docs contains a full example on implementing the arithmetic operations for your custom classes.
The proper way to handle incompatible types is to return the special value NotImplemented
.
Special value which should be returned by the binary special methods (e.g.
__eq__()
,__lt__()
,__add__()
,__rsub__()
, etc.) to indicate that the operation is not implemented with respect to the other type
Suppose you try to use a unsupported complex number, returning NotImplemented
will eventually cause a TypeError
with a correct error message. (at least in python 3)
>>> 100j / Time(2)Traceback (most recent call last): File "python", line 1, in <module>TypeError: unsupported operand type(s) for /: 'complex' and 'Time'
you need to implement __rtruediv__
and__rfloordiv__
.
from the documentation
object.__radd__(self, other)object.__rsub__(self, other)object.__rmul__(self, other)object.__rmatmul__(self, other)object.__rtruediv__(self, other)object.__rfloordiv__(self, other)object.__rmod__(self, other)object.__rdivmod__(self, other)object.__rpow__(self, other)object.__rlshift__(self, other)object.__rrshift__(self, other)object.__rand__(self, other)object.__rxor__(self, other)object.__ror__(self, other)
These methods are called to implement the binary arithmetic operations (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation [3] and the operands are of different types. [4] For instance, to evaluate the expression x - y, where y is an instance of a class that has an
__rsub__()
method,y.__rsub__(x)
is called ifx.__sub__(y)
returns NotImplemented.