Python中和第三方扩展中几乎没有不可变类型;提问者正确地指出“线性代数有足够多的用途,看起来我不得不自己编写”,但是我所知道的所有执行线性代数的现有类型都是可变的!因此,由于提问者坚持使用不可变类型,他只能自己编写。
并不是说需要做很多工作,例如,如果你确切地需要2-d向量:
import math
class ImmutableVector(object):
__slots__ = ('_d',)
def __init__(self, x, y):
object.__setattr__(self, _d, (x, y))
def __setattr__(self, n, v):
raise ValueError("Can't alter instance of %s" % type(self))
@property
def x(self):
return self._d[0]
@property
def y(self):
return self._d[1]
def __eq__(self, other):
return self._d == other._d
def __ne__(self, other):
return self._d != other._d
def __hash__(self):
return hash(self._d)
def __add__(self, other):
return type(self)(self.x+other.x, self.y+other.y)
def __mul__(self, scalar):
return type(self)(self.x*scalar, self.y*scalar)
def __repr__(self):
return '%s(%s, %s)' % (type(self).__name__, self.x, self.y)
def __abs__(self):
return math.hypot(self.x, self.y)
我“免费添加”了一些额外的功能,例如.x
和.y
只读属性、良好的字符串表示、可用于集合或作为字典键(否则为什么要不可变性?),低内存占用,abs(v)
返回v
的向量长度--我相信您可以想到其他“如果有就太酷了”的方法和运算符,取决于您的应用领域,它们同样容易。如果您需要其他维度,这不会更难,尽管稍微不那么易读,因为.x
、.y
表示法不再适用;-)(但我会使用生成器表达式而不是map
)。