如何制作 2 种不同的 __mul__ 方法
How to make 2 different __mul__ methods
我构建了一个矩阵计算器并且
我想制作一个 mul 方法乘以标量,另一种方法乘以其他矩阵。我有一个 if-else 块,但我更喜欢它有两种不同的方法,但我希望它们都与 * operator 一起使用。我应该怎么做?
您可以使用 __mul__
(*
) 和 __matmul__
(@
) 或者,如果您只想使用一个没有 if
的运算符, 使用 singledispatchmethod
(Python 3.8+).
import functools
class Matrix:
@functools.singledispatchmethod
def __mul__(self, other):
raise NotImplementedError(other)
@__mul__.register
def _(self, other: int):
print('int')
@__mul__.register
def _(self, other: str):
print('str')
Matrix() * 1 # 'int'
Matrix() * 'a' # 'str'
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]
如果使用早于 3.8 的 Python 版本 -(在这种情况下,最好只在一个方法中进行类型检查而不使用装饰器):
>>> 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]
>>>
我构建了一个矩阵计算器并且 我想制作一个 mul 方法乘以标量,另一种方法乘以其他矩阵。我有一个 if-else 块,但我更喜欢它有两种不同的方法,但我希望它们都与 * operator 一起使用。我应该怎么做?
您可以使用 __mul__
(*
) 和 __matmul__
(@
) 或者,如果您只想使用一个没有 if
的运算符, 使用 singledispatchmethod
(Python 3.8+).
import functools
class Matrix:
@functools.singledispatchmethod
def __mul__(self, other):
raise NotImplementedError(other)
@__mul__.register
def _(self, other: int):
print('int')
@__mul__.register
def _(self, other: str):
print('str')
Matrix() * 1 # 'int'
Matrix() * 'a' # 'str'
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]
如果使用早于 3.8 的 Python 版本 -(在这种情况下,最好只在一个方法中进行类型检查而不使用装饰器):
>>> 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]
>>>