Scrapy Item類分析


class BookItem(Item):
    name=Field()
    price=Field()
book=BookItem(name='abc',price=43)

在這里BookItem 繼承Item類,並且有2個類屬性:name和price。都是類Field的實例。

@six.add_metaclass(ItemMeta)
class Item(DictItem):
    pass

這里表示Item繼承於DictItem。並且使用元類ItemMeta創建Item這個類實例。

class ItemMeta(ABCMeta):

    def __new__(mcs, class_name, bases, attrs):
        classcell = attrs.pop('__classcell__', None)
        new_bases = tuple(base._class for base in bases if hasattr(base, '_class'))
        _class = super(ItemMeta, mcs).__new__(mcs, 'x_' + class_name, new_bases, attrs)

        fields = getattr(_class, 'fields', {})
        new_attrs = {}
        for n in dir(_class):
            v = getattr(_class, n)
            if isinstance(v, Field):
                fields[n] = v
            elif n in attrs:
                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)

在這里__new__的參數傳入分別是(ItemMeta,BookItem,Item,( ('name',{}),('price',()) ))    PS:可參考 www.cnblogs.com/solakevon/p/8894822.html

因為在使用元類創建類實例時,會把類名,父類名,類屬性傳入。和使用type創建類實例一樣。

new_bases是個空元祖。_class是x_item類。類屬性和BookItem一樣.

在for循環里面會把在attrs里面Field的實例給傳到fields這個字典里面。其他非Field實例的類屬性都放到new_attrs里面

最后把fields這個字典也放到new_attrs里面。此時fields里面有name和price。

class DictItem(MutableMapping, BaseItem):

    fields = {}

    def __init__(self, *args, **kwargs):
        self._values = {}
        if args or kwargs:  # avoid creating dict for most common case
            for k, v in six.iteritems(dict(*args, **kwargs)):
                self[k] = v

    def __getitem__(self, key):
        return self._values[key]

    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]

    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)

    def __len__(self):
        return len(self._values)

    def __iter__(self):
        return iter(self._values)

    __hash__ = BaseItem.__hash__

    def keys(self):
        return self._values.keys()

    def __repr__(self):
        return pformat(dict(self))

    def copy(self):
        return self.__class__(self)

在DictItem將會實現Item對象的一些功能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM