[Python] Class 的 member function 每次取得位址不同

[Python] Class 的 member function 每次取得位址不同

專案的程式最近遇到一個問題,

同事把一個 class 的 member function 加到 list 裡面作 callback 用,

為了預防重覆,因此會用類似 if func in list_func 的寫法來判斷,

但後來發現這招無效,每次 func 的位址都不一樣…

 

查了一下,原來 python 裡的 member function 是每次存取時,

都會產生一個新的物件,所以位址是不一樣的,

這跟 C++ 是蠻不同的概念~

 

參考資料:

stackoverflow: Why don’t methods have reference equality?

stackoverflow: Why does id() of an unbound method in Python 2 change for every access

 

做個實驗吧~先建立五個 A 物件:

>>> class A(object):
...     def foo(self):
...             print "foo"
...
>>> a_list = [A() for i in xrange(5)]
>>> pprint([a.foo for a in a_list])
[<bound method A.foo of <__main__.A object at 0x108dd7150>>,
<bound method A.foo of <__main__.A object at 0x108dd7190>>,
<bound method A.foo of <__main__.A object at 0x108dd71d0>>,
<bound method A.foo of <__main__.A object at 0x108dd7210>>,
<bound method A.foo of <__main__.A object at 0x108dd7250>>]

 

比較看看… 嗯,這五個 A 物件指到的 foo 全都不一樣:

>>> a_list[0].foo == a_list[1].foo
False
>>> a_list[0].foo == a_list[2].foo
False

 

foo 是一個 instancemethod 物件:

>>> type(a_list[0].foo)
<type 'instancemethod'>
>>> dir(a_list[0].foo)
['__call__', '__class__', '__cmp__', '__delattr__', '__doc__', '__format__', '__func__', '__get__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__self__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'im_class', 'im_func', 'im_self']

 

若是真的要比較它們指向的是不是同一個 member function 的話,

可以看一下 im_func 屬性,就會是一樣的了:

>>> pprint([a.foo.im_func for a in a_list])
[<function foo at 0x108dbfed8>,
<function foo at 0x108dbfed8>,
<function foo at 0x108dbfed8>,
<function foo at 0x108dbfed8>,
<function foo at 0x108dbfed8>]
>>> a_list[0].foo.im_func == a_list[1].foo.im_func
True

 

感想:python 真的跟 C/C++ 很不同呀…

 

 

(本頁面已被瀏覽過 421 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料