Created
April 19, 2017 13:25
-
-
Save Hanaasagi/7b699c0d0b236a3984f6f35aba0887a9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*-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