当前位置:  开发笔记 > 编程语言 > 正文

Python懒惰列表

如何解决《Python懒惰列表》经验,为你挑选了2个好方法。

我想创建自己的集合,它具有python列表的所有属性,并且还知道如何在数据库中保存/加载自身.此外,我想使加载隐式和惰性,因为它不会在创建列表时发生,而是等到它第一次使用时.

有没有一种单一的__xxx__方法,我可以覆盖上加载任何列表属性的第一次使用的列表(如len,getitem,iter而不必重写他们... ...等)?



1> Glyph..:

不完全是.对于模拟的东西其他比列表,有__getattribute__,但不幸的是Python不认为像运营商x[y]或者x(y)正好相同x.__getitem__(y)x.__call__(y).像这样的运算符是类的属性,而不是实例的属性,如下所示:

>>> class x(object):
...     def __getattribute__(self, o):
...         print o
... 
>>> x()[3]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'x' object does not support indexing

但是,您可以利用Python的动态特性来有效地消除这种区别.如果您主要关注的是保存自己的输入,并生成需要维护的代码较少,那么您可以执行以下操作:

class override(object):
    def __init__(self, methodName):
        self.methodName = methodName

    def __get__(self, oself, cls):
        oself._load(self.methodName)
        return getattr(super(oself.__class__, oself), self.methodName)

class LazyList(list):
    def _load(self, name):
        print 'Loading data for %s...' % (name,)

    for methodName in set(dir(list)) - set(dir(object)):
        locals()[methodName] = override(methodName)

您可能不想dir()在现实生活中使用,但合适的固定字符串列表可以作为替代.



2> Lauritz V. T..:

不是单一的,但5就足够了:

from collections import MutableSequence

class Monitored(MutableSequence):
    def __init__(self):
        super(Monitored, self).__init__()
        self._list = []

    def __len__(self):
        r = len(self._list)
        print "len: {0:d}".format(r)
        return r

    def __getitem__(self, index):
        r = self._list[index]
        print "getitem: {0!s}".format(index)
        return r

    def __setitem__(self, index, value):
        print "setitem {0!s}: {1:s}".format(index, repr(value))
        self._list[index] = value

    def __delitem__(self, index):
        print "delitem: {0!s}".format(index)
        del self._list[index]

    def insert(self, index, value):
        print "insert at {0:d}: {1:s}".format(index, repr(value))
        self._list.insert(index, value)

检查某些内容是否实现整个列表界面的正确方法是检查它是否是其子类MutableSequence.在collections模块中找到的ABC ,其中MutableSequence有一个,有两个原因:

    允许您创建自己的类来模拟内部容器类型,以便它们可以在普通内置函数的任何位置使用.

    用作参数isinstanceissubclass验证对象是否实现了必要的功能:

>>> isinstance([], MutableSequence)
True
>>> issubclass(list, MutableSequence)
True

我们Monitored班的工作方式如下:

>>> m = Monitored()
>>> m.append(3)
len: 0
insert at 0: 3
>>> m.extend((1, 4))
len: 1
insert at 1: 1
len: 2
insert at 2: 4
>>> m.l
[3, 1, 4]
>>> m.remove(4)
getitem: 0
getitem: 1
getitem: 2
delitem: 2
>>> m.pop(0)   # after this, m.l == [1]
getitem: 0
delitem: 0
3
>>> m.insert(0, 4)
insert at 0: 4
>>> m.reverse()   # After reversing, m.l == [1, 4]
len: 2
getitem: 1
getitem: 0
setitem 0: 1
setitem 1: 4
>>> m.index(4)
getitem: 0
getitem: 1
1

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有