Python中常见的特殊方法-魔术方法介绍

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

 

你可能感兴趣的:(Python)