如何延迟加载数据结构(python)

2024-01-09

我有一些构建数据结构的方法(例如,从一些文件内容中):

def loadfile(FILE):
    return # some data structure created from the contents of FILE

所以我可以做类似的事情

puppies = loadfile("puppies.csv") # wait for loadfile to work
kitties = loadfile("kitties.csv") # wait some more
print len(puppies)
print puppies[32]

在上面的例子中,我实际上浪费了很多时间阅读kitties.csv并创建一个我从未使用过的数据结构。我想避免这种浪费而不需要不断检查if not kitties每当我想做某事时。我希望能够做到

puppies = lazyload("puppies.csv") # instant
kitties = lazyload("kitties.csv") # instant
print len(puppies)                # wait for loadfile
print puppies[32]

所以如果我不尝试做任何事kitties, loadfile("kitties.csv")永远不会被叫到。

有一些标准方法可以做到这一点吗?

经过一番尝试后,我生成了以下解决方案,该解决方案似乎可以正常工作并且非常简短。有一些替代方案吗?使用这种方法有什么我应该记住的缺点吗?

class lazyload:
    def __init__(self,FILE):
        self.FILE = FILE
        self.F = None
    def __getattr__(self,name):
        if not self.F: 
            print "loading %s" % self.FILE
            self.F = loadfile(self.FILE)
        return object.__getattribute__(self.F, name)

如果这样的事情有效的话可能会更好:

class lazyload:
    def __init__(self,FILE):
        self.FILE = FILE
    def __getattr__(self,name):
        self = loadfile(self.FILE) # this never gets called again
                                   # since self is no longer a
                                   # lazyload instance
        return object.__getattribute__(self, name)

但这不起作用,因为self是本地的。它实际上最终调用loadfile每次你做任何事情的时候。


Python stdlibrary 中的 csv 模块在您开始迭代数据之前不会加载数据,因此它实际上是惰性的。

编辑:如果您需要通读整个文件来构建数据结构,那么拥有一个复杂的延迟加载对象来代理事物就太过分了。只需这样做:

class Lazywrapper(object):
    def __init__(self, filename):
        self.filename = filename
        self._data = None

    def get_data(self):
        if self._data = None:
            self._build_data()
        return self._data

    def _build_data(self):
        # Now open and iterate over the file to build a datastructure, and
        # put that datastructure as self._data

通过上面的类,你可以这样做:

puppies = Lazywrapper("puppies.csv") # Instant
kitties = Lazywrapper("kitties.csv") # Instant

print len(puppies.getdata()) # Wait
print puppies.getdata()[32] # instant

Also

allkitties = kitties.get_data() # wait
print len(allkitties)
print kitties[32]

如果你有一个lot数据,并且您实际上并不需要加载所有数据,您还可以实现类似类的东西,该类将读取文件,直到找到名为“Froufrou”的小狗,然后停止,但此时最好坚持数据一次性保存在数据库中并从那里访问它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何延迟加载数据结构(python) 的相关文章

随机推荐