Skip to content

Instantly share code, notes, and snippets.

@Hanaasagi
Created April 19, 2017 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Hanaasagi/7b699c0d0b236a3984f6f35aba0887a9 to your computer and use it in GitHub Desktop.
Save Hanaasagi/7b699c0d0b236a3984f6f35aba0887a9 to your computer and use it in GitHub Desktop.
# -*-coding:UTF-8-*-
import six
class Field(object):
def __init__(self, key, default=None):
self.key = key
class BaseMapper(type):
def __new__(cls, name, bases, attrs):
opt = {}
base_opts = []
for base_class in bases:
if hasattr(base_class, '_meta'):
base_opt = base_class._meta.copy()
opt.update(base_opt)
for k, v in attrs.items():
if isinstance(v, Field):
opt[k] = [v]
attrs['_meta'] = opt
return type.__new__(cls, name, bases, attrs)
class Mapper(six.with_metaclass(BaseMapper)):
def __init__(self, data=None, **options):
self.data = data
self.options = options
if isinstance(self.data, dict):
self.data.update(self.options)
def _get(self, name):
if isinstance(self.data, dict):
value = self.data[name]
else:
try:
value = getattr(self.data, name)
except AttributeError:
value = None
return value
def as_dict(self):
dic = {}
for key, value in self._meta.items():
for field in value:
dic[key] = self._get(field.key)
return dic
class TestMapper(Mapper):
foo = Field('foo')
class InheritMapper(TestMapper):
foo = Field('var')
foo2 = Field('bar')
class InheritMapper2(InheritMapper):
pass
# simple test
assert TestMapper(dict(foo=123, bar='abc', var=['hehe'])).as_dict() == {'foo': 123}
assert InheritMapper(dict(foo=123, bar='abc', var=['hehe'])).as_dict() == \
InheritMapper2(dict(foo=123, bar='abc', var=['hehe'])).as_dict()
class Data(object):
def __init__(self, var):
self.var = var
assert InheritMapper2(Data('test')).as_dict() == {'foo': 'test', 'foo2': None}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment