python - Proxy class for sequences that can be indexable or just iterable -
in python 3.x, trying implement class proxy sequence given parameter. proxy takes function called on each element of input sequence.
what correct way proxy class implement __getitem__, __iter__ , __len__ methods dynamically depending on availability in input sequence. here attempt @ doing (i calling sequences "providers" , function "transform"):
class transformproviderproxy: def __init__(self, input_provider, transform): self.input_provider = input_provider self.transform = transform def __iter__(self): # use generator expressions produce new iterator when requested return (self.transform(data_sample) data_sample in self.input_provider) def __getattr__(self, name): if name == "__getitem__" , hasattr(self.input_provider, "__getitem__"): return self._getitem_impl elif name == "__len__" , hasattr(self.input_provider, "__len__"): return self._len_impl else: return none def _getitem_impl(self, index): return self.transform(self.input_provider[index]) def _len_impl(self): return len(self.input_provider) however fails because seems python bypasses __getattr__ when looking __getitem__. correct way ?
as bonus, there way while having proxy class inherit dynamically collections.abc.sequence or collections.abc.iterable depending on input sequence ?
ps: thought implementing __getitem__ anyway , relying on catching typeerror when trying call on non-indexable input sequence, able check if proxy class indexable looking presence of __getitem__ without having explicitly call index.
just implement __getitem__ , __len__. fail appropriate error message if input_provider doesn't implement these operations:
class transformproviderproxy: def __init__(self, input_provider, transform): self.input_provider = input_provider self.transform = transform def __iter__(self): # use generator expressions produce new iterator when requested return (self.transform(data_sample) data_sample in self.input_provider) def __getitem__(self, index): return self.transform(self.input_provider[index]) def __len__(self): return len(self.input_provider) just example:
>>> t = transformproviderproxy(2, lambda x: x+2) >>> t[1] typeerror: 'int' object not subscriptable >>> t = transformproviderproxy([1,2,3,4], lambda x: x+2) >>> t[1] 4
Comments
Post a Comment