class Vector2d:
...: typecode = 'd'
...: def __init__(self,x,y):
...: self.__x = float(x) # 私有变量
...: self.__y = float(y)
...: @property
...: def x(self):
...: # 读取,v1.x相同方式读取
...: return self.__x
...: @property
...: def y(self):
...: return self.__y
...: def __iter__(self):
...: return (i for i in (self.x,self.y))
...: def __repr__(self):
# eval(repr(v1))==v1
...: class_name = type(self).__name__
...: return '{}({!r},{!r})'.format(class_name,*self)
...: def __str__(self):
# print调用该方法
...: return str(tuple(self))
...: def __bytes__(self):
# 转为字节码
...: return (bytes([ord(self.typecode)]) + bytes(array(self.typecode,self)))
...: @classmethod
...: def from_bytes(cls,octets):
# Vector2d.from_bytes(bytes(v1)) == v1
...: typecode = chr(octets[0])
...: memv = memoryview(octets[1:]).cast(typecode) # memoryview是数组的一种
...: return cls(*memv)
...: def __eq__(self,other):
# 注意特性[3.0,4.0] == print(v1)
...: return tuple(self) == tuple(other)
...: def __abs__(self):
# 计算模长
...: return math.hypot(self.x,self.y)
def __bool__(self):
# bool(v1),若abs(v1)==0则返回Flase
...: return bool(abs(self))
...: def angle(self):
...: return math.atan2(self.y,self.x)
...: def __format__(self,fmt_spec=''):
# 极坐标形式
...: if fmt_spec.endswith('p'):
...: fmt_spec = fmt_spec[:-1]
...: cood = (abs(self),self.angle())
...: outer_fmt = '<{},{}>'
...: else:
...: cood = self
...: outer_fmt = '({},{})'
...: components = (format(c,fmt_spec) for c in cood) # 数字的小格式
...: return outer_fmt.format(*components)
...: def __hash__(self):
# 散列化
...: return hash(self.x)^hash(self.y)
class Vector:
...: typecode = 'd'
...: def __init__(self,components):
...: self._components = array(self.typecode,components)
...: def __iter__(self):
...: return iter(self._components)
...: def __repr__(self):
...: components = reprlib.repr(self._components) # 将超长变量变成...
...: components = components[components.find('['):-1] # 将数组形式进行提取,find函数返回位置
...: return 'Vector({})'.format(components)
...: def __str__(self):
...: return str(tuple(self))
...: def __bytes__(self):
...: return (bytes([ord(self.typecode)])+bytes(self._components))
...: def __hash__(self):
...: hashes = map(hash,self._components)
...: return functools.reduce(operator.xor,hashes,0)# 异或运算需要设置0为初始值,以防报错
...: def __eq__(self,other):
...: return (len(self)==len(other)) and all(a==b for a,b in zip(self,other))
...: def __abs__(self):
...: return math.sqrt(sum(x*x for x in self))
...: def __bool__(self):
...: return bool(abs(self))
...: def __len__(self):
...: return len(self._components)
...: def __getitem__(self,index):
...: # 定义了该方法和len方法就是实现鸭子类型,序列
...: cls = type(self)# 备用
...: if isinstance(index,slice):
...: return cls(self._components[index]) # 如果是切片则返回实例对象
...: def __getattr__(self,name):
...: # 当属性查找失败的时候会调用该方法
...: cls = type(self)
...: if len(name)==1:
...: pos = cls.shortcut_names.find(name)
...: if 0<=pos