Scribbling

Python: Pythonic Object 본문

Computer Science/Python

Python: Pythonic Object

focalpoint 2022. 4. 5. 12:23

 

What is a "Pythonic Object"?

An object with many different magic methods seems to be more pythonic. However, it doesn't necessarily refer to a class with a lot of magic methods. That is, we don't have to implement all the magic methods in every class. Instead, implement them if only needed, because 'being simple' is pythonic.

 

Below is Vector2D class example.

from array import array
import math

class Vector2d:
    __slots__ = ('__x', '__y')

    typecode = 'd'

    @classmethod
    def frombytes(cls, octests):
        typecode = chr(octests[0])
        memv = memoryview(octests[1:]).cast(typecode)
        return cls(*memv)

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

    @property
    def x(self):
        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):
        class_name = type(self).__name__
        return f"{class_name}({self.x!r}, {self.y!r})"

    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))

    def __format__(self, fmt_spec=''):
        if fmt_spec.endswith('p'):
            fmt_spec = fmt_spec[:-1]
            coords = (abs(self), self.angle)
            outer_fmt = '<{}, {}>'
        else:
            coords = self
            outer_fmt = '({}, {})'
        components = (format(c, fmt_spec) for c in coords)
        return outer_fmt.format(*components)

    @property
    def angle(self):
        return math.atan2(self.y, self.x)

    def __hash__(self):
        return hash(self.x) ^ hash(self.y)


class ShortVector2d(Vector2d):
    typecode = 'f'


v1 = Vector2d(2.1, 1)
x, y = v1
print(f"{v1:.5p}")
print(hash(v1))

v2 = ShortVector2d(1/11, 1/29)
print(repr(v2))

 

'Computer Science > Python' 카테고리의 다른 글

Python: ABC Class  (0) 2022.04.07
Python: Sequence Protocol  (0) 2022.04.06
Python: Object References  (0) 2022.04.04
Python: Decorator & Closure  (0) 2022.03.29
Python: Design Patterns  (0) 2022.03.25