Overriding definitions for mutable objects

This example will continue using the Cards class. The idea of mutable cards is strange, perhaps even wrong. However, we'd like to apply just one small tweak to the previous examples.

The following is a class hierarchy that provides us with the definitions of __hash__() and __eq__(), appropriate for mutable objects. The parent class is as follows:

class Card3:
insure = False

def __init__(self, rank: str, suit: "Suit", hard: int, soft: int) -> None:
self.rank = rank
self.suit = suit
self.hard = hard
self.soft = soft

def __repr__(self) -> str:
return f"{self.__class__.__name__}(suit={self.suit!r}, rank={self.rank!r})"

def __str__(self) -> str:
return f"{self.rank}{self.suit}"

def __eq__(self, other: Any) -> bool:
return (
self.suit == cast(Card3, other).suit
and self.rank == cast(Card3, other).rank
)

A subclass of Card3 is shown in the following example:

class AceCard3(Card3):
insure = True

def __init__(self, rank: int, suit: "Suit") -> None:
super().__init__("A", suit, 1, 11)

Let's see how objects of these classes behave. We expect them to compare as equal but not work at all with sets or dictionaries. We'll create two objects as follows:

>>> c1 = AceCard3(1, '♣') 
>>> c2 = AceCard3(1, '♣') 

We've defined two instances of what appear to be the same card.

We'll look at their ID values to ensure that they really are distinct:

>>> id(c1), id(c2)
(4302577040, 4302577296)

No surprise here. Now, we'll see if we can get hash values:

>>> hash(c1), hash(c2)
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'AceCard3' 

The Card3 objects can't be hashed. They won't provide a value for the hash() function. This is the expected behavior. However, we can perform equality comparisons, as shown in the following code snippet:

>>> c1 == c2
True 

The equality test works properly, allowing us to compare cards. They just can't be inserted into sets or used as keys in a dictionary.

The following is what happens when we try to put them into a set:

>>> set([c1, c2])
Traceback (most recent call last): 
  File "<stdin>", line 1, in <module> 
TypeError: unhashable type: 'AceCard3' 

We get a proper exception when trying to do so.

Clearly, this is not a proper definition for something that – in real life – is immutable, such as a card. This style of definition is more appropriate for stateful objects, such as Hand, where the content of the hand is always changing. We'll provide you with a second example of stateful objects in the following section.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset