web-dev-qa-db-ja.com

id()を使用するときに[]とlist()に違いはありますか?

誰かが以下を説明できますか?

なぜidは同じですが、リストは異なりますか?

>>> [] is []
False
>>> id([]) == id([])
True

リストの作成に違いはありますか?

>>> id(list()) == id(list())
False
>>> id([]) == id([])
True

なんでこんなことが起こっているの? 2つの異なるリストを取得します。なぜ1つだけ、または3つ以上ではないのですか?

>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868128>
>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x7fd2be868170>
38
Vlad Okrimenko

id()を間違って使用しました。 id([])は、すぐに破棄されるオブジェクトのメモリIDを取ります。結局、id()が処理されると、もう参照することはありません。したがって、次回id([]) Pythonを使用すると、メモリとloを再利用する機会があり、それらのアドレスは実際に同じです。

ただし、これは実装の詳細であり、信頼できないものであり、メモリアドレスを常に再利用できるとは限りません。

id()の値は、オブジェクトの有効期間中のみ一意であることに注意してくださいドキュメント を参照してください。

これは、このオブジェクトの存続期間中に一意で一定であることが保証されている整数です。 重複しないライフタイムを持つ2つのオブジェクトは、同じid()値を持つことができます。

(太字強調鉱山)。

id(list())がメモリ位置を再利用できないのは、おそらくスタック上の現在のフレームをプッシュして関数を呼び出し、list()呼び出しが戻ります。

[]list()は両方とも、new空のリストオブジェクトを生成します。ただし、これらの個別のリスト(ここではab)への参照を最初に作成する必要があります。

>>> a, b = [], []
>>> a is b
False
>>> id(a) == id(b)
False
>>> a, b = list(), list()
>>> a is b
False
>>> id(a) == id(b)
False

[].__repr__を使用した場合も同じことが起こります。 Pythonインタラクティブインタープリターには特別なグローバル名_があり、これを使用して最後に生成された結果を参照できます。

>>> [].__repr__
<method-wrapper '__repr__' of list object at 0x10e011608>
>>> _
<method-wrapper '__repr__' of list object at 0x10e011608>

これにより追加の参照が作成されるため、__repr__メソッド、および拡張機能で作成した空のリストは、まだアクティブと見なされます。メモリの場所は解放されず、作成する次のリストでは使用できません。

しかし、[].__repr__を再度実行すると、Pythonが_をその新しいメソッドオブジェクトにバインドします。突然、以前の__repr__メソッドが参照されなくなり、リストオブジェクトも解放されます。

[].__repr__を3回実行すると、最初のメモリ位置が再利用できるようになります。したがって、Pythonはそれを行います:

>>> [].__repr__  # create a new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> _            # now _ points to the new method
<method-wrapper '__repr__' of list object at 0x10e00cb08>
>>> [].__repr__  # so the old address can be reused
<method-wrapper '__repr__' of list object at 0x10e011608>

3つ以上のリストを作成することはできません。前のもの(まだ_によって参照されているもの)と現在のもの。より多くのメモリロケーションを表示する場合は、変数を使用して別の参照を追加します。

76
Martijn Pieters