Skip to content

Instantly share code, notes, and snippets.

@ByK95
Created August 10, 2021 15:47
Show Gist options
  • Save ByK95/157ccd65ea625227522df95fb63f5737 to your computer and use it in GitHub Desktop.
Save ByK95/157ccd65ea625227522df95fb63f5737 to your computer and use it in GitHub Desktop.
example of chaining and class attribute usage like drf
import functools
class Field(object):
def __init__(self, *args, **kwargs):
pass
class ChainAbleMixin(object):
def __getattr__(self, item):
if item != 'then':
raise AttributeError(item)
return self.chain
def chain(self, *args, **kwargs):
cls = args[0]
setattr(self, 'next', cls)
return self
class ReduceFrom(ChainAbleMixin, Field):
def __init__(self, *args, **kwargs):
super(ReduceFrom, self).__init__(*args, **kwargs)
self.lookup = args[0]
def get_value(self):
return functools.reduce(dict.get, self.lookup, self.context)
class CastInto(ChainAbleMixin, Field):
def __init__(self, *args, **kwargs):
super(CastInto, self).__init__(*args, **kwargs)
self.type = args[0]
def get_value(self):
return self.type(self.context)
class Mapping(Field):
_skip_fields = ['process', 'chain']
def process(self):
fields = [field for field in dir(self) if not field.startswith('_')
and field not in self._skip_fields]
for field in fields:
cls = getattr(self, field)
setattr(cls, 'context', self._data)
while hasattr(cls, 'next'):
value = cls.get_value()
cls = getattr(cls, 'next')
setattr(cls, 'context', value)
value = cls.get_value()
setattr(self, field, value)
class PriceMapping(Mapping):
price = ReduceFrom(['paraparapara']).then(CastInto(int))
a = PriceMapping()
a._data = {'paraparapara': '11'}
a.process()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment