如何编写两个不同的 __mul__ 方法

3

我建了一个矩阵计算器,我想做一个用于标量乘法的mul方法和另一个用于矩阵乘法的方法。我有一个if-else块,但我更喜欢它分成两个不同的方法,但我希望它们都能使用*运算符工作。我该怎么做?


1
使用 __mul__ (*) 和 __matmul__ (@)。 - askaroni
我想起了functools.singledispatch... - Todd
你好,欢迎来到StackOverflow!你在这里询问了__mul__,但也许这个类似的问题关于__add__会对你有所帮助。不过遗憾的是,那里的解决方案似乎不能帮助你定义两种不同的方法。 - Alex Telon
2个回答

5
您可以使用__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'

1
"

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]
>>> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接