我有一个班级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
答案 0 :(得分:1)
让我尝试改进你的问题然后回答它。提供包装器的唯一情况是,如果您有一个可能的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
答案 1 :(得分:0)
原样,您的完整列表已经在内存中,因为您已经设置并定义了所有实体。
datas1()
只会引用self.lst
列表对象datas2()
将返回一个迭代器对象datas3()
将返回生成器对象有关每个内容的更多信息,请阅读文档(&#34;解释生成器和迭代器是什么&#34;不在话题)。
如果您没有计划任何额外的功能,那么您没有理由实施此功能,因为将来会出现这种情况。你为未知数过度编程。如果以后需要lst
采取不同的行为,或者在其上添加功能,则可以选择扩展列表类来处理它。没有理由重写和重新填充已经存在的功能。