Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a __repr__ of a namedtuple?

How do I create a special method __repr__ where I can print, for example, '6 of spades' or 'Q of diamonds'?

How do I access the data from the namedtuple, keeping in mind that I have a list of namedtuples in self._cards?

import collections

cards = collections.namedtuple('Card', ['rank', 'suit'])

class Deck:
    ranks = [str(n) for n in range (2,11)] + list('JQKA')
    suits = 'spades diamonds hearts clubs'.split()

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

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

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

    def __repr__(self):
        return '%s of %s' % ()  # <-- don't know how to assign the string

b = ()
for i in b:
    print(i)
like image 618
Piontk Avatar asked Dec 23 '18 00:12

Piontk


People also ask

Can you modify a Namedtuple?

Since a named tuple is a tuple, and tuples are immutable, it is impossible to change the value of a field. In this case, we have to use another private method _replace() to replace values of the field. The _replace() method will return a new named tuple.

Can Namedtuple have methods?

index() , namedtuple classes also provide three additional methods and two attributes. To prevent name conflicts with custom fields, the names of these attributes and methods start with an underscore. In this section, you'll learn about these methods and attributes and how they work.

Can you pickle a Namedtuple?

@Antimony: pickle handles namedtuple classes just fine; classes defined in a function local namespace not so much.


2 Answers

It would be clearer if you renamed cards to Card, since that's the name you assigned to that class:

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

You can extend a namedtuple just like any other class, including to give it __repr__ method. You can even reuse the class name, since a class statement is a type of assignment:

class Card(Card):
    def __repr__(self):
        return f'{self.rank} of {self.suit}'

A more compact version would be

class Card(collections.namedtuple('Card', ['rank', 'suit'])):
    def __repr__(self):
        return f'{self.rank} of {self.suit}'
like image 65
Mad Physicist Avatar answered Sep 22 '22 04:09

Mad Physicist


You could use typing.NamedTuple instead, which allows you to define methods normally:

from typing import NamedTuple

class Card(NamedTuple):
    rank: str
    suit: str
    def __repr__(self):
        return "{} of {}".format(self.rank, self.suit)
like image 23
Patrick Haugh Avatar answered Sep 23 '22 04:09

Patrick Haugh