Scribbling

Python Magic Methods: Pythonic Data Model 본문

Computer Science/Python

Python Magic Methods: Pythonic Data Model

focalpoint 2022. 3. 16. 13:54

 

In this post, I am dealing with 'magic methods' to create more pythonic data models.

First Example: Card Deck

Card = namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = ['Spades', 'Diamonds', 'Hearts', 'Clubs']

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in FrenchDeck.suits for rank in FrenchDeck.ranks]

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, index):
        return self._cards[index]

First, namedtuple is used to create a simple data class for cards.

Next, I implemented 'FrenchDeck' class with magic methods, which are __len__ and __getitem__. If these two methods are defined, FrenchDeck object can be dealt with the same way like other sequence objects.

 

What are the things that we can do with usual sequence objects?

We can use [], in operators, iterate it, and even sort it like below.

Deck = FrenchDeck()
print(Deck[17])
print(Deck[51])

print(Deck[21:23])

print(choice(Deck))

for card in Deck:
    print(card)
    break

for card in reversed(Deck):
    print(card)
    break

print(Card('Q', 'Diamonds') in Deck)


def sequence(card):
    rank_value = FrenchDeck.ranks.index(card.rank)
    return rank_value * 4 + FrenchDeck.suits.index(card.suit)

for card in sorted(Deck, key=sequence):
    print(card)

 

Second Example: Vector Class

from math import hypot

class Vector:

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Vector({self.x!r}, {self.y!r})"

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

    def __bool__(self):
        return bool(abs(self))

    def __add__(self, other):
        return Vector(self.x+other.x, self.y+other.y)

    def __mul__(self, scalar):
        return Vector(self.x*scalar, self.y*scalar)
v1 = Vector(2, 4)
v2 = Vector(2, 1)
print(v1+v2)
print(abs(v1))
print(v1*3)
print(bool(Vector(0, 0)))

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

Python Immutable Dictionary, Set  (0) 2022.03.22
Python Data Structures: Sequences  (0) 2022.03.21
Python Grammar: Things that I forget often  (0) 2022.03.14
Python String Methods  (0) 2022.01.18
Python Int Representation & Bit Operations  (0) 2022.01.13