zhanghaitao1
6/3/2019 - 2:03 PM

class, templates

class, templates


from array import array
import math

class Vector2d:
    typecode='d'

    def __init__(self,x,y):
        self.__x=float(x)
        self.__y=float(y)

    @property #@property decorator marks the getter method of a property
    def x(self):
        return self.__x

    @property
    def y(self):
        return self.__y

    def __hash__(self):
        '''
        To make a Vector2d hashable we must implement __hash__ (__eq__ is also required).
        We also need to make vector instances immutable.
        '''
        return hash(self.x)^hash(self.y)

    def __iter__(self):
        '''
        __iter__ makes a Vector2d iterale; this is what makes unpacking work, e.g, x,y=my_vector,
        *self, tuple(self) and so on.
        '''
        return (i for i in (self.x,self.y))

    def __repr__(self):
        class_name=type(self).__name__ #trick: type().__name__
        #_repr__builds a string by interpolating the components with {!r} to get their repr
        # *self feeds the x and y components to format
        return '{}({!r},{!r})'.format(class_name,*self)

    def __str__(self):
        return str(tuple(self))

    def __bytes__(self):
        return (bytes([ord(self.typecode)]))+bytes(array(self.typecode,self))

    def __eq__(self, other):
        return tuple(self)==tuple(other)

    def __abs__(self):
        return math.hypot(self.x,self.y)

    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 __format__(self, format_spec=''):
        components=(format(c,format_spec) for c in self)
        return '({},{})'.format(*components)