国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

舉例講解Python中is和id的用法

2020-02-23 00:30:12
字體:
來源:轉載
供稿:網友

(ob1 is ob2) 等價于 (id(ob1) == id(ob2))

首先id函數可以獲得對象的內存地址,如果兩個對象的內存地址是一樣的,那么這兩個對象肯定是一個對象。和is是等價的。Python源代碼為證。
 

static PyObject * cmp_outcome(int op, register PyObject *v, register PyObject *w){ int res = 0; switch (op) { case PyCmp_IS: res = (v == w); break; case PyCmp_IS_NOT:res = (v != w); break;

但是請看下邊代碼的這種情況怎么會出現呢?

In [1]: def bar(self, x):...:   return self.x + y...: In [2]: class Foo(object):...:   x = 9...:   def __init__(self ,x):...:     self.x = x...:   bar = bar...:   In [3]: foo = Foo(5) In [4]: foo.bar is Foo.barOut[4]: False In [5]: id(foo.bar) == id(Foo.bar)Out[5]: True

兩個對象用is判斷是False,用id判斷卻是True,這與我們已知的事實不符啊,這種現象該如何解釋呢?遇到這種情況最好的解決方法就是調用dis模塊去看下兩個比較語句到底做了什么。

In [7]: dis.dis("id(foo.bar) == id(Foo.bar)")     0 BUILD_MAP    10340     3 BUILD_TUPLE   28527     6 <46>          7 DELETE_GLOBAL  29281 (29281)     10 STORE_SLICE+1      11 SLICE+2         12 DELETE_SUBSCR      13 DELETE_SUBSCR      14 SLICE+2         15 BUILD_MAP    10340     18 PRINT_EXPR       19 JUMP_IF_FALSE_OR_POP 11887     22 DELETE_GLOBAL  29281 (29281)     25 STORE_SLICE+1  In [8]: dis.dis("foo.bar is Foo.bar")     0 BUILD_TUPLE   28527     3 <46>          4 DELETE_GLOBAL  29281 (29281)     7 SLICE+2         8 BUILD_MAP    8307     11 PRINT_EXPR       12 JUMP_IF_FALSE_OR_POP 11887     15 DELETE_GLOBAL  29281 (29281)

真實情況是當執行.操作符的時候,實際是生成了一個proxy對象,foo.bar is Foo.bar的時候,兩個對象順序生成,放在棧里相比較,由于地址不同肯定是False,但是id(foo.bar) == id(Foo.bar)的時候就不同了,首先生成foo.bar,然后計算foo.bar的地址,計算完之后foo.bar的地址之后,就沒有任何對象指向foo.bar了,所以foo.bar對象就會被釋放。然后生成Foo.bar對象,由于foo.bar和Foo.bar所占用的內存大小是一樣的,所以又恰好重用了原先foo.bar的內存地址,所以id(foo.bar) == id(Foo.bar)的結果是True。

下面內容由郵件Leo Jay大牛提供,他解釋的更加通透。

用id(expression a) == id(expression b)來判斷兩個表達式的結果是不是同一個對象的想法是有問題的。

foo.bar 這種形式叫 attribute reference [1],它是表達式的一種。foo是一個instance object,bar是一個方法,這個時候表達式foo.bar返回的結果叫method object [2]。根據文檔:

    When an instance attribute is referenced that isn't a data attribute,
    its class is searched. If the name denotes a valid class attribute

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 汤原县| 宁蒗| 桓台县| 玉环县| 哈巴河县| 资阳市| 龙山县| 雅江县| 营山县| 同心县| 分宜县| 新龙县| 和静县| 新晃| 岑巩县| 海宁市| 辽源市| 滦平县| 湘潭县| 神池县| 台山市| 海原县| 临泉县| 江川县| 榆中县| 交口县| 乌鲁木齐市| 赤水市| 札达县| 琼结县| 许昌市| 平果县| 株洲市| 佛冈县| 鄂托克旗| 天峨县| 黄平县| 北流市| 怀集县| 平乐县| 嵊州市|