每当数据发生变化时,如何子列表并触发事件?

时间:2016-08-28 09:36:07

标签: python

我希望子类class MyList(list): def __init__(self, sequence): super().__init__(sequence) self._test() def __setitem__(self, key, value): super().__setitem__(key, value) self._test() def append(self, value): super().append(value) self._test() def _test(self): """ Some kind of check on the data. """ if not self == sorted(self): raise ValueError("List not sorted.") 并在每次数据发生任何更改时触发事件(数据检查)。这是一个示例子类:

__init__

在这里,我重写方法__setitem____append__和{{1}}来检查数据是否发生变化。我认为这种方法是不可取的,所以我的问题是:如果任何类型的突变发生在底层数据结构中,是否有可能自动触发数据检查?

1 个答案:

答案 0 :(得分:7)

正如你所说,这不是最好的方法。要正确实现这一点,您需要了解可以更改列表的每种方法。

要走的路是实现自己的列表(或者更确切地说是一个可变序列)。执行此操作的最佳方法是使用您在collections.abc模块中找到的Python中的抽象基类。您必须只实现最少量的方法,模块会自动为您实现其余的方法。

对于您的具体示例,这将是这样的:

from collections.abc import MutableSequence

class MyList(MutableSequence):

    def __init__(self, iterable=()):
        self._list = list(iterable)

    def __getitem__(self, key):
        return self._list.__getitem__(key)

    def __setitem__(self, key, item):
        self._list.__setitem__(key, item)
        # trigger change handler

    def __delitem__(self, key):
        self._list.__delitem__(key)
        # trigger change handler

    def __len__(self):
        return self._list.__len__()

    def insert(self, index, item):
        self._list.insert(index, item)
        # trigger change handler

性能

某些方法的默认实现速度很慢。例如,__contains__中的def __contains__(self, value): for v in self: if v is value or v == value: return True return False 定义如下:

//$dd = array(-50, -25, -5, -80, -40, -152, -45, -28, -455, -100, -98, -455);
$dd = array(50, -25, -5, 80, -40, -152, -45, 28, -455, 100, 98, -455);
//$dd = array(50, 25, 5, 80, 40, 152, 45, 28, 455, 100, 98, 455);
$curr = '';
$max = $dd[0];

for($i = 0; $i < count($dd); $i++) {
    $curr = $dd[$i];

    if($curr >= $max) {
        $max = $curr;   
    }
}

echo "greatest number is $max";

根据您的课程,您可以更快地实施此课程。但是,性能通常不如编写易于理解的代码重要。它还可以使写一个类更难,因为你负责正确地实现这些方法。