diff --git a/scrapy/trunk/scrapy/contrib_exp/newitem/declarative.py b/scrapy/trunk/scrapy/contrib_exp/newitem/declarative.py new file mode 100644 index 000000000..73618825c --- /dev/null +++ b/scrapy/trunk/scrapy/contrib_exp/newitem/declarative.py @@ -0,0 +1,18 @@ +class DeclarativeMeta(type): + """Metaclass for declarative objects""" + + def __new__(meta, class_name, bases, attrs): + cls = type.__new__(meta, class_name, bases, attrs) + cls.__classinit__.im_func(cls, attrs) + return cls + + +class Declarative(object): + """Base class for declarative objects""" + + __metaclass__ = DeclarativeMeta + + def __classinit__(cls, attrs): + """Override this method to initialize your class""" + pass + diff --git a/scrapy/trunk/scrapy/contrib_exp/newitem/models.py b/scrapy/trunk/scrapy/contrib_exp/newitem/models.py index 4354303a8..0d38316b2 100644 --- a/scrapy/trunk/scrapy/contrib_exp/newitem/models.py +++ b/scrapy/trunk/scrapy/contrib_exp/newitem/models.py @@ -1,19 +1,25 @@ from scrapy.item import ScrapedItem +from scrapy.contrib_exp.newitem.declarative import Declarative from scrapy.contrib_exp.newitem.fields import Field -class Item(ScrapedItem): - """ - This is the base class for all scraped items. - """ +class Item(Declarative, ScrapedItem): + """ This is the base class for all scraped items. """ + + fields = {} + + def __classinit__(cls, attrs): + cls.fields = cls.fields.copy() + for n, v in attrs.items(): + if isinstance(v, Field): + cls.fields[n] = v def __init__(self): self._values = {} - self._fields = self._get_fields() - def _get_fields(self): - return dict(i for i in self.__class__.__dict__.iteritems() \ - if isinstance(i[1], Field)) + @property + def _fields(self): + return self.__class__.fields def __setattr__(self, name, value): if not name.startswith('_'):