Data Classes for Comparison
Comparison. In many card games, cards are compared to each other. For instance, in a typical trick taking game, the highest card takes the trick. As it is currently implemented, the
PlayingCard class does not support this kind of comparison.
This is, however, seemingly easy to rectify. The
@dataclass decorator has two forms. So far, you’ve used this simple form where
@dataclass is specified without any parentheses or parameters. However, you can also give parameters to the decorator in parentheses.
These are the parameters that are supported.
init: add an
.__init__() method. The default is
repr: add a
The default is
eq: add an
.__eq__() method. The default is
order: add ordering methods.
The default here is
unsafe_hash: force the addition of a
.__hash__() method. The default is
True, assigning to fields raises an exception. The default is
So, let’s see if we can make use of
order to solve our problem.
order to be
True, instances of
PlayingCard can be compared. How are the two cards compared, though? You’ve not specified how the ordering should be done, and for some reason Python seems to believe that a queen is higher than an ace.
It turns out that data classes compare objects as if they were tuples of their fields. In other words, a queen is higher than an ace because
'Q' comes after
'A' in the alphabet.
That doesn’t really work for us. Instead, we need to define some kind of sort index that uses the order of
SUITS, something like seen onscreen now.
PlayingCard to use this sort index for comparisons, we need to add a field
.sort_index to the class. However, this field should be calculated from the other fields
This is exactly what the special method
.__post_init__() is for. It allows for special processing after the regular
.__init__() method is called.
.sort_index is added as the first field of the class. This way, the comparison is first done using
.sort_index, and only if there are ties are any of the other fields used. Using
field(), you must also specify that
.sort_index should not be included as a parameter in the
.__init__() method, because it’s calculated from the
To avoid confusing the user about this implementation detail, it’s probably also a good idea to remove
.sort_index from the
repr of the class, as has been done in the code you’ve just seen. Finally, aces are high.
05:39 You can now easily create a sorted deck. And if you don’t care about sorting, this is how you draw a random hand of ten cards. In the next section of the course, you’ll take a look at how to make data classes immutable.
Become a Member to join the conversation.