fields = getattr(_class, 'fields', {})
new_attrs = {}
for n in dir(_class):
v = getattr(_class, n) # 依次判断每个属性的值是不是dict,如果是的话就把字段名加入fields这个字典
if isinstance(v, Field): # 默认的字段的值是个{}
fields[n] = v
elif n in attrs: # 处理_class的一些其他属性
new_attrs[n] = attrs[n]
new_attrs['fields'] = fields
new_attrs['_class'] = _class
if classcell is not None:
new_attrs['__classcell__'] = classcell
return super(ItemMeta, mcs).__new__(mcs, class_name, bases, new_attrs) # 生成最终的item对象
DictItem:
import item时,先创建DictItem对象,但不执行任何方法
class DictItem(MutableMapping, BaseItem):
fields = {} # 用来存放允许的字段值
# item的初始化,在新建一个item对象时运行,可以给_values字典一些值,一般用不到。
# 也就是说初始化时其实可以传参,给一些限制外的字段。。
def __init__(self, *args, **kwargs): #common init with no para
self._values = {} # only create _values dict
if args or kwargs: # avoid creating dict for most common case
for k, v in six.iteritems(dict(*args, **kwargs)):
self[k] = v
# 如果值不在field中,就抛出异常
def __setitem__(self, key, value):
if key in self.fields:
self._values[key] = value
else:
raise KeyError("%s does not support field: %s" %
(self.__class__.__name__, key))
def __delitem__(self, key):
del self._values[key]
# 本来字典类型不会有双下getattr,双下setattr这些方法,但是因为继承了BaseItem的缘故,需要覆盖这两个方法
# 赋值操作直接引起异常
def __getattr__(self, name):
if name in self.fields:
raise AttributeError("Use item[%r] to get field value" % name)
raise AttributeError(name)
def __setattr__(self, name, value):
if not name.startswith('_'):
raise AttributeError("Use item[%r] = %r to set field value" %
(name, value))
super(DictItem, self).__setattr__(name, value)