运算符重载
运算符重载(operator overloading),在定义类时通过运算符重载使类的实例可以使用一些运算符。默认情况下,运算符的操作都是python定义好的。自定类时可以对运算符进行自定义,使运算符按自定义的操作进行计算。
如,a+b语句,a和b均为列表时,默认执行列表拼接的操作,[1, 2, 3]+[1, 0, 0]得到列表[1, 2, 3, 1, 0, 0]。在类中自定义a+b语句执行向量加法运算,a和b为向量对象,[1, 2, 3]+[1, 0, 0]得到向量[2, 2, 3]。
特殊方法重载
Python支持大量特殊方法的重载,特殊方法以双下划线开头和结尾,有__len__、__geitem__、__setitem__、__str__、__repr__等等,通过重写特殊方法使自定义类也具有特殊方法对应的功能。如特殊方法__len__的功能是调用len函数统计序列元素的数量,__getitem__的功能是通过索引值series[index]来访问序列的元素。
用print函数打印对象时往往显示对象的类型,可以在类中重写__repr__方法把对象转换为字符串形式,来显示对象的内容。
class Vector:
"""n维向量"""
def __init__(self, d):
"""创建d维向量,初始值为0"""
self._coords = [0] * d
def __len__(self):
"""返回向量的维度"""
return len(self._coords)
def __getitem__(self, j):
"""返回向量第j维的坐标"""
return self._coords[j]
def __setitem__(self, j, val):
"""设置向量第j维为指定数值"""
self._coords[j] = val
def __add__(self, other): # other是可通过索引遍历的迭代对象,未必是Vector类
"""返回两向量的和"""
if len(self) != len(other): # 依赖 __len__方法
raise ValueError("两个向量的维度必须相同")
result = Vector(len(self))
for j in range(len(self)):
result[j] = self[j] + other[j]
return result
def __eq__(self, other):
"""如果两向量相同,返回True"""
return self._coords == other._coords
def __ne__(self, other):
"""如果不同于另一个向量,返回True"""
return not self == other # 依赖与__eq__方法
def __repr__(self): # 对象作为列表元素时,打印列表对象的字符串形式
"""返回向量的字符串形式"""
return "(" + str(self._coords)[1:-1] + ")"
# def __str__(self): # 对象作为列表元素时,打印列表还是显式对象的类型
# """返回向量的字符串形式"""
# return "(" + str(self._coords)[1:-1] + ")"
if __name__ == '__main__':
v = Vector(5) # 创建5维向量(0,0,0,0,0)
v[1] = 3 # 通过__setitem__方法
v[-1] = 3
u = v + v # 通过__add__方法
print([v, v]) # 通过__repr__方法
print(v[1]) # 通过__getitem__方法
print(u)
total = 0
for i in v:
total += i
print(total)
u1 = v + [1, 2, 3, 1, 5] # 通过__add__方法
print(u1)