Howto singledispatch on class vs instance

426 views Asked by At

This is essentially a syntactic sugar question, so if you do not approve of putting effort into that kind of thing read no further.

Consider the following toy example which does not work:

from functools import singledispatch

class rows_or_cols:
    _data = [[2,7,6],[9,5,1],[4,3,8]]
    def __init__(self, row_idx_or_col):
        self.data = row_idx_or_col if isinstance(row_idx_or_col, list) else \
                    self._data[row_idx_or_col]
    @singledispatch
    def __getitem__(self_or_cls, idx):
        return self_or_cls.data[idx]
    @__getitem__.register(type)
    @classmethod
    def _(cls, col_idx):
        return rows_or_cols([r[col_idx] for r in cls._data])
    def __repr__(self):
        return str(self.data)

What I want this to do is create instances containing either a row or a column of the magic square in _data depending on whether I use rows_or_cols(idx) or rows_or_cols[idx]. Complicating things is that I also want __getitem__ to be available on instances, so I can pick a sinlge element via rows_or_cols(ri)[ci] or rows_or_cols[ci][ri].

What doesn't work is the rows_or_cols[i] bit

a = rows_or_cols[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'type' object is not subscriptable

I think the reason is this https://stackoverflow.com/a/12447078/7207392

At this post they also suggest using a metaclass. I would, however, prefer to avoid them because I'm scared of metaclass conflicts.

Any recommendations (including those telling me that the whole thing is a stupid idea in the first place)?

0

There are 0 answers