functools.singledispatchmethod
кажется подходящим для того, что вы описываете. Другой пример использует аннотацию параметров для указания типов, или они могут быть указаны как параметры для декораторов:
>>> class Foo:
... def __init__(self, value):
... self._value = value
...
... @functools.singledispatchmethod
... def __mul__(self, other):
... print("hmm...")
...
... @__mul__.register(int)
... def _(self, other):
... print("Using the int version.")
... return self._value * other
...
... @__mul__.register(list)
... def _(self, other):
... print("Using the list version.")
... return [item * self._value for item in other]
...
>>> f = Foo(8)
>>> f * 3
Using the int version.
24
>>> f * [1, 2, 3]
Using the list version.
[8, 16, 24]
Если используется версия Python ранее 3.8 - (вероятно, лучше просто сделать тип проверка в пределах одного метода без использования декораторов в этом случае):
>>> class Foo:
... def __init__(self, value):
... self._value = value
... self.mul = functools.singledispatch(self.mul)
... self.mul.register(int, self.mul_int)
... self.mul.register(list, self.mul_list)
...
... def __mul__(self, other):
... return self.mul(other)
...
... def mul(self, other):
... print("Default mul() called.")
...
... def mul_int(self, other):
... print("Using the int version.")
... return self._value * other
...
... def mul_list(self, other):
... print("Using the list version.")
... return [item * self._value for item in other]
...
>>> f = Foo(3)
>>> f * 7
Using the int version.
21
>>> f * [1, 2, 3]
Using the list version.
[3, 6, 9]
>>>