イテレータは、メモリ内に「次の要素」を持たずにシーケンスの次の要素を生成できるように、十分な詳細が格納されているためです。我々は、私たちは次を生成可能にするのに十分な詳細(開始点と私たちのイテレータの終点)に格納されてきた私たちの__init__
方法で
class Fakeiterator:
def __init__(self, range_list):
self.current = range_list[0]
self.high = range_list[-1]
def __iter__(self):
return self
def __next__(self):
if self.current > self.high:
raise StopIteration
else:
self.current += 1
return self.current - 1
私たち自身の偽のイテレータを作成してみましょうに何が起こっているかを理解するには
要素を実際にメモリに入れないでください。この情報がある限り、2000要素を含むリストが与えられていても、開始点と終了点を知るだけで、イテレータの次の要素を求めるときはいつでも、開始点と終了点を知ることができます。
__next__
メソッド単に現在のカウンタをインクリメントして、それを私たちに返します。
>>> x = list(range(5))
>>> y = Fakeiterator(x)
>>> del x
>>> list(y)
[0, 1, 2, 3, 4]
>>>
list
コンストラクタを繰り返し呼び出すStopIteration
まで__next__
は、私たちのイテレータによって上昇し、それが現在の要素が、我々はの作成時に保存された最大の要素よりも高いポイントである:
は、私たちのイテレータをテストすることができますイテレータ
iter(x)
をリストに追加した場合はSTORES x内部でlist_iterator
オブジェクトを返します。 x
はまだ保存されていますが、名前はx
ではありません。
なぜgetsizeof
は、元のリストのサイズよりも大きいか、少なくとも等しいと思われる小さいサイズを返します。ドキュメントから
sys.getsizeof(オブジェクト[、デフォルト]) バイトのオブジェクトのサイズを返します。オブジェクトには、任意のタイプのオブジェクトを使用できます。すべてのビルトインオブジェクトは が正しい結果を返しますが、これは実装固有のものとして サードパーティの拡張機能には当てはまりません。
オブジェクトに直接起因するメモリ消費量は、参照するオブジェクトのメモリ消費ではなく、 です。
オブジェクトが サイズを取得する手段を提供していない場合、デフォルトが返されます。それ以外の場合は、TypeErrorが発生します。
getsizeof()オブジェクトののsizeofメソッドを呼び出して、オブジェクトが ガベージコレクタによって管理されている場合 追加のガベージコレクタのオーバーヘッドを付加します。それはあなたがスクリプトを実行するとのクイックスクリプト
import sys
x = [1, 2, 3]
print(sys.getsizeof(x))
class storex():
def __init__(self, param):
self.param = param
y = storex(x)
print(sys.getsizeof(y))
print(y.param, sys.getsizeof(y.param))
を書いてみましょう実証するために
。我々はそれが自動的に作成しませんstorex
の属性として保存するとき、リスト[1, 2, 2]
は、88バイト長であっても、これは(私のマシン上で、それはあなたと同じでなければなりません)が出力され
88
56
[1, 2, 3] 88
storex
がそれより大きくなります。 storex
がそれを参照しているためです。それは直接
storex
の一部ではありません。しかしy.param
のサイズを印刷するには、我々はそれがまだ元[1, 2, 3]
リストと同じサイズだと見ることができます。またdel
メモリからオブジェクトを削除しません
、それは単にアンバインドx
という名前で、xはメモリ内のオブジェクトを参照しません。 xの値は、それへの参照が再び存在しない場合にここで
iは
>>> x = [1,2,3]
>>> class y: pass
...
>>> y.x = x
>>> id(x), id(y.x)
(140177507371016, 140177507371016)
>>> del x
>>> id(y.x)
140177507371016
>>> x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>>
がx
を削除すると、自動的に[1,2,3]
たy.x
ポイントを削除しない何を意味するかのデモンストレーションです(ガベージコレクション)破棄されますto、彼らの両方のIDがメモリ内の同じオブジェクトを指していることをIDで示したとしても。
短い答え....元のシーケンスを再現するのに十分な情報がカプセル化されているので...あなたがそれを消費するとき – danidee