重载 + 以支持元组
我想在Python中写一些像这样的代码:
a = (1, 2)
b = (3, 4)
c = a + b # c would be (4, 6)
d = 3 * b # d would be (9, 12)
我知道可以重载运算符来处理自定义类,但有没有办法重载运算符来处理成对的数据呢?
当然,像这样的解决方案
c = tuple([x+y for x, y in zip(a, b)])
是可以工作的,但如果不考虑性能,它们看起来没有重载 +
运算符那么好看。
当然,你可以定义 add
和 mul
这样的函数:
def add((x1, y1), (x2, y2)):
return (x1 + x2, y1 + y2)
def mul(a, (x, y)):
return (a * x, a * y)
但能够写 q * b + r
而不是 add(times(q, b), r)
会更好。
有什么想法吗?
补充说明:顺便提一下,我意识到因为 +
目前是用来连接元组的,所以重新定义它可能不太明智,即使这是可能的。这个问题对于 -
也是适用的,比如说 =)
7 个回答
2
用Python的复数来处理这个问题绝对是一个方法,虽然看起来不太美观。
a = 1 + 2j
b = 3 + 4j
c = a + b # c would be 4 + 6j
d = 3 * b # d would be 9 + 12j
这样就不需要再定义一个额外的类了。
另外,进一步补充之前的回答,
class T(tuple):
def __add__((x, y), (x1, y1)):
return T((x+x1, y+y1))
def __rmul__((x, y), other):
return T((other * x, other * y))
这样可以提高性能,不过会限制实现只能使用成对的数据。
3
你可以从 tuple
这个类继承,并且重写它的 __add__
方法。下面是一个非常简单的例子:
class mytuple(tuple):
def __add__(self, other):
assert len(self) == len(other)
return tuple([x + y for x, y in zip(self, other)])
mt = mytuple((5, 6))
print mt + (2, 3) # prints (7, 9)
不过我不太推荐这种做法,因为元组本身并不是为了这个目的设计的。如果你想进行数字计算,直接使用 numpy
就好了。
7
和Ruby不同,在Python中你不能改变内置类型的行为。你能做的就是创建一个新的类型,这个新类型是从内置类型“派生”出来的。不过,直接写出来的字面量还是会生成内置类型。
你能做到的可能就是这样:
class T(tuple):
def __add__(self, other):
return T(x + y for x, y in zip(self, other))
def __rmul__(self, other):
return T(other * x for x in self)
a = T((1, 2))
b = T((3, 4))
c = a + b # c would be (4, 6)
d = 3 * b # d would be (9, 12)