2

この質問は単なる好奇心からです。

Python のオブジェクト モデルのドキュメントを読んでいるときに、クラス メソッドの ID を少し試してみることにしました。この動作を見つけました。

 Python 3.2.2 (default, Sep  4 2011, 09:07:29) [MSC v.1500 64 bit (AMD64)] on win32
 Type "copyright", "credits" or "license()" for more information.
 >>> class A():
    def a(self):
        pass


 >>> id(A().a)
 54107080
 >>> id(A().a)
 54108104
 >>> id(A().a)
 54107080
 >>> id(A().a)
 54108104
 >>> 
 >>> id(A().a)
 54108104
 >>> 
 >>> id(A().a)
 54108104
 >>> id(A().a)
 54107080
 >>> 

メソッドの ID は、行のパリティによって変わります!

私は実際に同じクラスのインスタンスをいくつか作成し、それらが同じメソッドオブジェクトを持っているかどうかを確認したかったのですが、それらがまったく同じであるか、毎回変更されると予想していましたが、メソッド ID がインタプリタの行が偶数かどうかに関係します! 何か案は?

注:ドキュメントとインタープリターのバージョンが一致していないことはわかっています。たまたまWindowsを使用していて、3.2しかインストールされていません

4

1 に答える 1

2

行が何をするかを説明id(A().a)します:

A() # creates a new object I call a

それで

A().a # creates a function f bound to a
A.a.__get__(A(), A) # same as above

>>> A.a.__get__(A(), A)
<bound method A.a of <__main__.A object at 0x02D85550>>
>>> A().a
<bound method A.a of <__main__.A object at 0x02D29410>>

このバインドされた関数には別のオブジェクトがあるため、常に別の関数です。__self__

>>> a = A()
>>> assert a.a.__self__ is a

__self__self関数 Aa の最初の引数として渡されます

編集:これは次のようになります。

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> class A:
    def a(self):
        pass


>>> id(A().a)
43476312
>>> id(A().a)
49018760

ここで、id は abab のように繰り返されます

Python 3.2.2 (default, Sep  4 2011, 09:51:08) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> class A:
    def a(self):
        pas
        s


>>> id(A().a)
50195512
>>> id(A().a)
50195832
>>> id(A().a)
50195512
>>> id(A().a)
50195832

編集:Linuxの場合、または私のマシンではないもの、および私が知らないものは何でも

id(A().a)

これを変数に格納する場合を除いて、常に同じ結果が得られます。理由はわかりませんが、パフォーマンスの最適化のためだと思います。スタック上のオブジェクトの場合、関数を呼び出すたびにオブジェクトに新しい領域を割り当てる必要はありません。

于 2013-03-10T11:49:52.320 に答える