Skip to content

Instantly share code, notes, and snippets.

@w495
Created October 29, 2017 16:25
Show Gist options
  • Save w495/511027960a28f2eba7abe3697aeba975 to your computer and use it in GitHub Desktop.
Save w495/511027960a28f2eba7abe3697aeba975 to your computer and use it in GitHub Desktop.
# -*- coding: utf8 -*-
from __future__ import absolute_import, print_function
import six
class BaseFieldDao(object):
_value = None
_entity = None
def __init__(self, entity=None, value=None, name=None):
encoded_value = self.encode(value)
self._value = encoded_value
self._entity = entity
self._name = name
@property
def value(self):
value = self._value
decoded_value = self.decode(value)
return decoded_value
def encode(self, value):
return value
def decode(self, value):
return value
class IdFieldDao(BaseFieldDao):
pass
from collections import OrderedDict
class FieldDescDict(OrderedDict):
def __getattr__(self, item):
if item in self:
return self[item]
else:
base = super(FieldDescDict, self)
res = getattr(base, item)
return res
class FieldDict(OrderedDict):
def __getattr__(self, item):
if item in self:
return self[item]
else:
base = super(FieldDict, self)
res = getattr(base, item)
return res
class BaseDaoFieldDesc(object):
field_type = BaseFieldDao
def get_field(self, entity=None, value=None, name=None):
field = self.field_type(
name=name,
value=value,
entity=entity
)
return field
class IdDaoFieldDesc(BaseDaoFieldDesc):
field_type = IdFieldDao
class AbsDao(object):
@property
def field_desc_dict(self):
return FieldDescDict()
@property
def full_field_desc_dict(self):
return self.field_desc_dict
@property
def field_dict(self):
return FieldDict()
def __init__(self, **kwargs):
for field_name, field_value in six.iteritems(kwargs):
setattr(self, field_name, field_value)
def copy(self, **kwargs):
cls = type(self)
arg_dict = OrderedDict(
(field_name, field.value)
for field_name, field in six.iteritems(self.field_dict)
)
arg_dict.update(kwargs)
inst = cls(**arg_dict)
return inst
def __setattr__(self, key, value):
sentinel = object()
field_desc = self.full_field_desc_dict.get(key, sentinel)
if field_desc is not sentinel:
field = field_desc.get_field(
name=key,
entity=self,
value=value
)
self.field_dict[key] = field
else:
super(AbsDao, self).__setattr__(key, value)
def __getattr__(self, key):
sentinel = object()
field_inst = self.field_dict.get(key, sentinel)
if field_inst is not sentinel:
return field_inst.value
return super(AbsDao, self).__getattribute__(key)
class BaseDao(AbsDao):
@property
def full_field_desc_dict(self):
cls = type(self)
base = super(cls, self)
base_fdd = base.field_desc_dict
full_fdd = FieldDescDict(base_fdd)
full_fdd.update(self.field_desc_dict)
return full_fdd
class ContentGroupDao(BaseDao):
field_desc_dict = FieldDescDict(
parent_id=IdDaoFieldDesc()
)
class EContentGroupDao(ContentGroupDao):
field_desc_dict = FieldDescDict(
parent_id2=IdDaoFieldDesc()
)
if __name__ == '__main__':
cx = EContentGroupDao(parent_id2=1)
ca = cx.copy()
ca.parent_id = 10
print('c.parent_id.value = ', cx.parent_id2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment