切片操作后保存对象类型的有效方法

时间:2015-04-18 16:25:17

标签: python performance oop casting slice

我正在寻找一种快速,干净和pythonic的方式来切割自定义对象,同时在操作后保留它们的类型。

为了给你一些上下文,我必须处理很多半非结构化数据并处理它我使用字典列表。为了简化某些操作,我创建了一个“ld”对象,它继承自“list”。在其众多功能中,它检查数据是否以正确的格式提供。让我们通过说它确保列表的所有条目都是包含一些键“a”的字典来简化它,如下所示:

class ld( list):
     def __init__(self, x):
          list.__init__(self, x)
          self.__init_check()

     def __init_check(self):
          for record in self:
               if isinstance( record, dict) and "a" in record:
                    pass
               else:
                     raise TypeError("not all entries are dictionaries or have the key 'a'")
          return

当数据符合要求并且初始化ld:

时,此行为正确
tt = ld( [{"a": 1, "b":2}, {"a":4}, {"a":6, "c":67}])
type( tt)

当数据不正确时,它也是正确的:

ld( [{"w":1}])
ld( [1,2,3])

然而,当我继续切片对象时会出现问题:

type( tt[:2])

tt [:2]是一个列表,不再是我在完全成熟的ld对象中创建的所有方法和属性。我可以将切片重新转换为ld,但这意味着它必须再次完成整个初始数据检查过程,从而大大减慢计算速度。

这是我提出的加速解决方案的解决方案:

class ld( list):
    def __init__(self, x, safe=True):
        list.__init__(self, x)
        self.__init_check( safe)

    def __init_check(self, is_safe):
        if not is_safe:
            return
        for record in self:
            if isinstance( record, dict) and "a" in record:
                pass
            else:
                raise TypeError("not all entries are dictionaries or have the key 'a'")
        return

    def __getslice__(self, i, j):
        return ld( list.__getslice__( self, i, j), safe=False)

是否有一种更干净,更灵巧的方式? 在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我不认为继承list来验证其内容的形状或类型通常是正确的方法。 list明确地不关心它的内容,并且实现一个类,其构造函数行为根据传递给它的标志而变化是混乱的。如果需要一个验证输入的构造函数,只需在返回列表的函数中执行检查逻辑。

def make_verified_list(items):
    """
    :type items: list[object]
    :rtype: list[dict]
    """
    new_list = []
    for item in items:
        if not verify_item(item):
             raise InvalidItemError(item)
        new_list.append(item)
    return new_list

def verify_item(item):
    """
    :type item: object
    :rtype: bool
    """
    return isinstance(item, dict) and "a" in item

采用这种方法,你不会发现自己在努力应对核心数据结构的行为。