これは非常に興味深い質問です。
あなたの条件下では、それらは同じように見えます:
Python 2.7.2 (default, Oct 11 2012, 20:14:37)
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> class Foo(object):
... def method(self): pass
...
>>> a, b = Foo(), Foo()
>>> a.method == b.method
False
>>> id(a.method), id(b.method)
(4547151904, 4547151904)
ただし、それらを使用して何かを行うと、それらは異なるものになることに注意してください。
>>> a_m = a.method
>>> b_m = b.method
>>> id(a_m), id(b_m)
(4547151*9*04, 4547151*5*04)
そして、再度テストすると、再び変更されました!
>>> id(b.method)
4547304416
>>> id(a.method)
4547304416
インスタンス上のメソッドにアクセスすると、「バインドされたメソッド」のインスタンスが返されます。バインドされたメソッドは、インスタンスとメソッドの関数オブジェクトの両方への参照を格納します。
>>> a_m
<bound method Foo.method of <__main__.Foo object at 0x10f0e9a90>>
>>> a_m.im_func is Foo.__dict__['method']
True
>>> a_m.im_self is a
True
( 「バインドされていないメソッド」が生成されるためFoo.__dict__['method']
、 ではなくを使用する必要があることに注意してください...その目的は、読者への演習として残されています)Foo.method
Foo.method
この「バインドされたメソッド」オブジェクトの目的は、メソッドが関数のように渡されるときに「適切に動作する」ようにすることです。たとえば、 functionを呼び出すと、明示的な参照がなくなったとしても、これはを呼び出すa_m()
ことと同じです。この動作を JavaScript (たとえば) と比較してください。JavaScript では、 と同じ結果は得られません。a.method()
a
var method = foo.method; method()
foo.method()
それで!id(a.method)
これにより、最初の質問に戻ります: がと同じ値を生成するように見えるのはなぜid(b.method)
ですか? 私は Asad が正しいと信じています。それは Python の参照カウント ガベージ コレクターと関係があります*: 式id(a.method)
が評価されると、バインドされたメソッドが割り当てられ、ID が計算され、バインドされたメソッドの割り当てが解除されます。次のバインドされたメソッド — for b.method
— が割り当てられると、メモリ内のまったく同じ場所に割り当てられます。これは、バインドされたメソッド for が割り当てられてから割り当てが行われていない (またはバランスの取れた数の割り当てが行われていない) ためa.method
です。これは、a.method
が と同じメモリ位置を持っているように見えることを意味しますb.method
。
最後に、2 回目のチェックでメモリ位置が変更されたように見える理由を説明します。1 回目と 2 回目のチェックの間に行われた他の割り当ては、2 回目は別の場所に割り当てられていることを意味します (注:それらへのすべての参照が失われたため再割り当てされます; バインドされたメソッドはキャッシュされます†、同じメソッドに 2 回アクセスすると同じインスタンスが返されます: a_m0 = a.method; a_m1 = a.method; a_m0 is a_m1 => True
)。
*: 衒学者の注: 実際には、これは実際のガベージ コレクターとは何の関係もありません。ガベージ コレクターは、循環参照を処理するためだけに存在します… しかし… それは別の日の話です。
†: 少なくとも CPython 2.7 では。CPython 2.6 はバインドされたメソッドをキャッシュしていないようです。そのため、動作が指定されていないことが予想されます。