I keep finding myself needing to test for objects that support subscripting. This is one case where EAFP is *not* actually easier: try: obj[0] except TypeError: subscriptable = False except (IndexError, KeyError): subscriptable = True else: subscriptable = True if subscriptable: ... But I don't like manually testing for it like this: if getattr(obj, '__getitem__', None) is not None: ... because it is wrong. (Its wrong because an object with __getitem__ defined as an instance attribute isn't subscriptable; it has to be in the class, or a superclass.) But doing it correctly is too painful: if any(getattr(T, '__getitem__', None) is not None for T in type(obj).mro()) and besides I've probably still got it wrong in some subtle way. What I'd really like to do is use the collections.abc module to do the check: if isinstance(obj, collections.abc.Subscriptable): ... in the same way we can check for Sized, Hashable etc. Alternatively, if we had a getclassattr that skipped the instance attributes, I could say: if getclassattr(obj, '__getitem__', None) is not None: ... (1) Am I doing it wrong? Perhaps I've missed some already existing solution to this. (2) If not, is there any reason why we shouldn't add Subscriptable to the collection.abc module? I think I have the implementation: class Subscriptable(metaclass=ABCMeta): __slots__ = () @abstractmethod def __getitem__(self, idx): return None @classmethod def __subclasshook__(cls, C): if cls is Subscriptable: return _check_methods(C, "__getitem__") return NotImplemented Comments, questions, flames? -- Steven
participants (18)
-
Andrew Barnert
-
Ben Rudiak-Gould
-
Brendan Barnwell
-
Chris Angelico
-
Christopher Barker
-
Devin Jeanpierre
-
Greg Ewing
-
Ivan Levkivskyi
-
Kyle Stanley
-
M.-A. Lemburg
-
MRAB
-
Neil Girdhar
-
Oscar Benjamin
-
Paul Moore
-
Richard Musil
-
Ricky Teachey
-
Stephen J. Turnbull
-
Steven D'Aprano