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

Popular posts from this blog

javascript - Create a stacked percentage column -

Optimising Firebase database by automatically overwriting data -

javascript - Angular UI-Grid customTemplate directive causing rows to load slowly/? -