class DeclarativeFieldsMetaclass(MediaDefiningClass): """ Metaclass that collects Fields declared on the base classes. """ def __new__(mcs, name, bases, attrs): # Collect fields from current class. current_fields = [] for key, value in list(attrs.items()): if isinstance(value, Field): current_fields.append((key, value)) attrs.pop(key) current_fields.sort(key=lambda x: x[1].creation_counter) attrs['declared_fields'] = OrderedDict(current_fields) new_class = (super(DeclarativeFieldsMetaclass, mcs) .__new__(mcs, name, bases, attrs)) # Walk through the MRO. declared_fields = OrderedDict() for base in reversed(new_class.__mro__): # Collect fields from base class. if hasattr(base, 'declared_fields'): declared_fields.update(base.declared_fields) # Field shadowing. for attr, value in base.__dict__.items(): if value is None and attr in declared_fields: declared_fields.pop(attr) new_class.base_fields = declared_fields new_class.declared_fields = declared_fields return new_class
DeclarativeFieldsMetaclass繼承MediaDefiningClass,。MediaDefiningClass是收集media信息的,在個人文章裏python
django.forms-Widget和Media間的聯繫有介紹。django
如今具體看看DeclarativeFieldsMetaclass是怎麼收集Field。app
它首先遍歷attrs,收集當前類聲明的Field。
spa
而後遍歷基類的declared_fields。去除基類的shadowing field(經過設置字段爲None)。.net