Classes#
You can use dispatch within classes:
from plum import dispatch
class Real:
@dispatch
def __add__(self, other: int):
return "int added"
@dispatch
def __add__(self, other: float):
return "float added"
>>> real = Real()
>>> real + 1
'int added'
>>> real + 1.0
'float added'
Decorators#
You can use @dispatch together with other decorators, provided the decorators are ordered correctly.
When combining @dispatch with other decorators (for example, @staticmethod, @classmethod, or @property), @dispatch should generally be the inner decorator (i.e., closest to the function definition) for dispatch to work correctly:
from plum import dispatch
class MyClass:
def __init__(self):
self._name = None
@property
def name(self):
return self._name
@name.setter
@dispatch
def name(self, value: str):
self._name = value
>>> a = MyClass()
>>> a.name = "1" # OK
>>> a.name = 1 # Not OK
NotFoundLookupError: For function `name` of `__main__.MyClass`, `(<__main__.MyClass object at 0x7f8cb8813eb0>, 1)` could not be resolved.
For example, when using @staticmethod, @dispatch should be the inner decorator (i.e., @dispatch wraps the function first):
from plum import dispatch
class MyClass:
@staticmethod
@dispatch
def my_func(a: int, b: int) -> int:
return a + b
@staticmethod
@dispatch
def my_func(a: float, b: float) -> float:
return a + b
>>> MyClass.my_func(1, 2)
3
>>> MyClass.my_func(1.0, 2.0)
3.0
Forward References#
Imagine the following design:
from plum import dispatch
class Real:
@dispatch
def __add__(self, other: Real):
...
If we try to run this, we get the following error:
NameError Traceback (most recent call last)
<ipython-input-1-2c6fe56c8a98> in <module>
1 from plum import dispatch
2
----> 3 class Real:
4 @dispatch
5 def __add__(self, other: Real):
<ipython-input-1-2c6fe56c8a98> in Real()
3 class Real:
4 @dispatch
----> 5 def __add__(self, other: Real):
6 ...
NameError: name 'Real' is not defined
The problem is that name Real is not yet defined, when __add__ is defined and
the type hint for other is set.
To circumvent this issue, you can use a forward reference:
from plum import dispatch
class Real:
@dispatch
def __add__(self, other: "Real"):
...