访问包装值、return 对象、迭代器或 yield?

access wrapped value, return object, iterator or yield?

我有一个 class ADT,里面有一个列表。我想通过函数访问数据来包装数据。我想出了以下访问数据的方法。 我只想知道这两种方式的区别,我应该选择哪一种。

class ADT(object):
    """The comments is a possible replace in the feture
    """
    def __init__(self)
        #... other data...
        self.adt = [1, 2, 3, 4]
        #self.adt = {1:2, 3:4}


    #... other logic...

    def datas1(self):
        return self.adt
        #return self.adt.items()

    def datas2(self):
        return iter(self.adt)
        #return iter(self.adt.items())

    def datas3(self):
        for i in self.adt:
            yield i
        #for i in self.adt.items():
        #   yield i

用例

l = ADT()
for i in l.datas(): #use datas1 or datas2 or datas3 as datas
    #do something

照原样,您的列表,完整的,已经在内存中,因为您已经设置并定义了它的所有实体。

  • datas1() 将只是对 self.lst 列表对象的引用
  • datas2() 将 return 一个迭代器对象
  • datas3() 将 return 生成器对象

有关每个内容的更多信息,请阅读文档(因为 "Explain what a generator and an iterator are" 与主题无关)。

如果您没有计划任何额外的功能,您就没有理由实施它,因为将来可能会这样。您对未知数进行了过度编程。如果稍后您希望 lst 采取不同的行为,或向其添加功能,您可以选择扩展列表 class 来处理。没有理由重写和重新包装已经存在的功能。

让我尝试改进您的问题然后回答。提供包装器唯一有意义的情况是,如果您有一个潜在的 large and lazy 序列开头:

class ADT(object):
    def __init__(self, count):
        # Count could be very large. Or maybe you want to perform a function 
        # on each value before passing it to adt, e.g.,
        # self.adt = (expensive_func(x) for x in xrange(count))  
        self.adt = xrange(count)  
        self.adt_as_list = list(self.adt)
        self.adt_as_iter = iter(self.adt)

    @property
    def adt_as_gen(self):
        for x in self.adt:
            y = yield
            yield x + y 

在这种情况下,您的选择取决于用例。

1.数据可以放入内存。使用列表。

l = ADT(10)
data = l.adt_as_list
data
>>> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

2。数据无法放入内存,但您只想循环 。直接使用属性。

l = ADT(10000)
data = l.adt
func = lambda x: x + 1
(func(x) for x in l.adt).next()
>>> 1

2。数据无法放入内存,您只需要下一个值。使用迭代器。

l = ADT(10000)
data = l.adt_as_iter
data.next()
>>> 0

2。你想使用 coroutine。使用发电机。

l = ADT(10000)
data = l.adt_as_gen
data.next()
data.send(2)
>>> 2