19

これはばかげた質問かもしれませんが、とにかく質問します。私はジェネレータオブジェクトを持っています:

>>> 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

誰かが私を教えてくれたらありがたいです。

4

5 に答える 5

38

__sizeof__()あなたが思っていることをしません。このメソッドは、ジェネレーターが返すアイテムの数ではなく、指定されたオブジェクトの内部サイズをバイト単位で返します。

Pythonはジェネレーターのサイズを事前に知ることはできません。たとえば、次のエンドレスジェネレーターを取り上げます(たとえば、カウンターを作成するためのより良い方法があります)。

def count():
    count = 0
    while True:
        yield count
        count += 1

そのジェネレーターは無限です。割り当て可能なサイズはありません。ただし、ジェネレータオブジェクト自体はメモリを使用します。

>>> count.__sizeof__()
88

通常、それを関数__sizeof__()に任せて呼び出すことはありません。これにより、ガベージコレクターのオーバーヘッドも追加されます。sys.getsizeof()

ジェネレーターが有限になることがわかっていてそれが返すアイテムの数を知る必要がある場合は、次を使用します。

sum(1 for item in generator)

しかし、それはジェネレータを使い果たすことに注意してください。

于 2012-09-18T13:17:47.047 に答える
8

他の回答で述べたように__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
于 2012-09-18T13:41:59.480 に答える
1

__sizeof__ジェネレーターの長さではなく、オブジェクトのメモリサイズをバイト単位で返します。ジェネレーターは無限に大きくなる可能性があるため、これを事前に決定することは不可能です。

于 2012-09-18T13:19:06.200 に答える
0

作成したジェネレーターが「有限」(要素の数が数えられる) であることが確実であり、しばらく待つことを気にしない場合は、次を使用して必要なものを取得できます。

len(list(gen()))

他のポスター__sizeof__()が言ったように、何かがどれだけのメモリを消費するかの尺度であり(おそらくほとんど必要としない低レベルの概念)、その長さではありません(数えられる長さがあるという保証がないため、ジェネレータの機能ではありません)。 .

于 2012-09-18T13:21:40.190 に答える
-1

@Martijn Pieters sizeof () 関数を上書きすることもできます。ここでやろうとしていることを達成できますが、int や float などの一部のデータ型では機能しません。

class GetLen():
    def __sizeof__(self, x):
        return len(x)

したがって、ここで int または float の場合、タイプが int または float の場合はエスケープ関数を配置することもできます。

于 2018-10-08T06:53:55.577 に答える