这可能是一个愚蠢的问题,但无论如何我都会问。我有一个生成器对象:
>>> def gen():
... for i in range(10):
... yield i
...
>>> obj=gen()
我可以测量它的大小:
>>> obj.__sizeof__()
24
据说发电机被消耗了:
>>> for i in obj:
... print i
...
0
1
2
3
4
5
6
7
8
9
>>> obj.__sizeof__()
24
...但obj.__sizeof__()
保持不变。
使用字符串可以按预期工作:
>>> 'longstring'.__sizeof__()
34
>>> 'str'.__sizeof__()
27
如果有人能够启发我,我将感激不尽。
答案 0 :(得分:27)
__sizeof__()
没有按照您的想法行事。该方法返回给定对象的内部大小(以字节为单位),而不是生成器将返回的项目数。
Python无法预先知道生成器的大小。以下面的无限生成器为例(例如,有更好的方法来创建计数器):
def count():
count = 0
while True:
yield count
count += 1
那个发电机是无止境的;没有可分配的大小。然而,生成器对象本身需要记忆:
>>> count.__sizeof__()
88
您通常不会将__sizeof__()
留给sys.getsizeof()
function,这也会增加垃圾收集器的开销。
如果您知道某个生成器将是有限的,并且您 知道它返回了多少项,请使用:
sum(1 for item in generator)
但请注意耗尽生成器。
答案 1 :(得分:6)
如其他答案所述,__sizeof__
会返回不同的内容。
只有一些迭代器具有返回未返回元素数的方法。例如,listiterator
具有相应的__length_hint__
方法:
>>> L = [1,2,3,4,5]
>>> it = iter(L)
>>> it
<listiterator object at 0x00E65350>
>>> it.__length_hint__()
5
>>> help(it.__length_hint__)
Help on built-in function __length_hint__:
__length_hint__(...)
Private method returning an estimate of len(list(it)).
>>> it.next()
1
>>> it.__length_hint__()
4
答案 2 :(得分:1)
__sizeof__
以字节为单位返回对象的内存大小,而不是生成器的长度,由于生成器可以无限增长,因此无法预先确定。
答案 3 :(得分:0)
如果您确定您创建的生成器是“有限的”(具有可数数量的元素)并且您不介意等待一段时间,您可以使用以下内容来获得您想要的内容:
len(list(gen()))
正如其他海报所说,__sizeof__()
衡量一些内存占用了多少(一个你可能很少需要的低级别概念),而不是它的长度(这不是发电机的一个特征,因为它有不保证他们有可数的长度。)
答案 4 :(得分:0)
@Martijn Pieters您可能还不愿意使用 sizeof ()函数,我们可以在此处实现此功能。但是它不适用于int或float这类数据类型。
class GetLen():
def __sizeof__(self, x):
return len(x)
因此对于int或float,如果类型为int或float,我们还可以放置一些转义函数。