vector的多维版本
1.一行代码实现如下功能
#方式一 # if len(self) != len(other): # return False # for a, b in zip(self, other): # if a != b: # return False # return True #方式二 return len(self) == len(other) and all(a == b for a, b in zip(self, other))
2.多维
import itertools import math from array import array import reprlib import numbers import operator import functools class Vector: typecode = 'd' shortcut_name = 'xyzt' def __init__(self, components): '''类外直接拿到属性''' self._components = array(self.typecode, components) def __iter__(self): '''返回可迭代的对象''' return iter(self._components) def __str__(self): return str(tuple(self)) def __repr__(self): # 获得有限的长度 components = reprlib.repr(self._components) components = components[components.find('['):-1] return 'Vector({})'.format(components) def __bytes__(self): return bytes([ord(self.typecode)]) + bytes(self._components) def __abs__(self): return math.sqrt(sum(i * i for i in self)) def __bool__(self): return bool(abs(self)) @classmethod def frombytes(cls, octets): typecode = chr(octets[0]) memv = memoryview(octets[1:]).cast(typecode) return cls(memv) def __len__(self): return len(self._components) def __getitem__(self, index): cls = type(self) if isinstance(index, slice): return cls(self._components[index]) elif isinstance(index, numbers.Integral): return self._components[index] else: msg = '{cls.__name__} indices must be integers' return TypeError(msg.format(cls)) def __getattr__(self, name): cls = type(self) if len(name) == 1: pos = self.shortcut_name.find(name) if 0 <= pos <= len(cls.shortcut_name): return self._components[pos] msg = '{.__name__!r} has not attribute {!r}' raise AttributeError(msg.format(cls, name)) def __setattr__(self, name, value): ''' 1.解决vector修改xyzt属性的问题 2.设置a to z的属性问题 3。继承父类的setattr的方法 ''' cls = type(self) if len(name) == 1: if name in cls.shortcut_name: error = 'readonly attribute {attr_name!r}' elif name.islower(): error = "can't set attribute 'a' to 'z' {cls_name!r}" else: error = '' if error: msg = error.format(attr_name=name, cls_name=cls.__name__) raise AttributeError(msg) super().__setattr__(name, value) def __eq__(self, other): # 方式一 # if len(self) != len(other): # return False # for a, b in zip(self, other): # if a != b: # return False # return True # 方式二 return len(self) == len(other) and all(a == b for a, b in zip(self, other)) def __hash__(self): hashes = (hash(x) for x in self._components) return functools.reduce(operator.xor, hashes) def angle(self, n): r = math.sqrt(sum(x * x for x in self)) a = math.atan2(r, self[n - 1]) if (n == len(self) - 1) and (self[-1] < 0): return math.pi * 2 - a else: return a def angles(self): return (self.angle(n) for n in range(1, len(self))) def __format__(self, format_spec): if format_spec.endswith('h'): format_spec = format_spec[:-1] coords = itertools.chain([abs(self)], self.angles()) outer_fmt = "<{}>" else: coords = self outer_fmt = "({})" components = (format(i, format_spec) for i in coords) return outer_fmt.format(' ,'.join(components))