欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python中的is和id用法分析

系統(tǒng) 1624 0

本文實(shí)例講述了Python中的is和id用法。分享給大家供大家參考。具體分析如下:

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

首先id函數(shù)可以獲得對(duì)象的內(nèi)存地址,如果兩個(gè)對(duì)象的內(nèi)存地址是一樣的,那么這兩個(gè)對(duì)象肯定是一個(gè)對(duì)象。和is是等價(jià)的。Python源代碼為證。

復(fù)制代碼 代碼如下:
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;

但是請(qǐng)看下邊代碼的這種情況怎么會(huì)出現(xiàn)呢?

復(fù)制代碼 代碼如下:
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.bar
Out[4]: False
?
In [5]: id(foo.bar) == id(Foo.bar)
Out[5]: True

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

復(fù)制代碼 代碼如下:
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)

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

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

用id(expression a) == id(expression b)來判斷兩個(gè)表達(dá)式的結(jié)果是不是同一個(gè)對(duì)象的想法是有問題的。

foo.bar 這種形式叫 attribute reference [1],它是表達(dá)式的一種。foo是一個(gè)instance object,bar是一個(gè)方法,這個(gè)時(shí)候表達(dá)式foo.bar返回的結(jié)果叫method object。根據(jù)文檔:

When an instance attribute is referenced that isn't a data attribute,
its class is searched. If the name denotes a valid class attribute
that is a function object, a method object is created by packing
(pointers to) the instance object and the function object just found
together in an abstract object: this is the method object.

foo.bar本身并不是簡(jiǎn)單的名字,而是表達(dá)式的計(jì)算結(jié)果,是一個(gè) method object,在id(foo.bar)這樣的表達(dá)式里,method object只是一個(gè)臨時(shí)的中間變量而已,對(duì)臨時(shí)的中間變量做id是沒有意義的。

一個(gè)更明顯的例子是,

復(fù)制代碼 代碼如下:
print id(foo.bar) == id(foo.__init__)

輸出的結(jié)果也是True

看 id 的文檔:

Return the “identity” of an object. This is an integer (or long
integer) which is guaranteed to be unique and constant for this object
during its lifetime. Two objects with non-overlapping lifetimes may
have the same id() value.
CPython implementation detail: This is the address of the object in memory.

只有你能保證對(duì)象不會(huì)被銷毀的前提下,你才能用 id 來比較兩個(gè)對(duì)象。所以,如果你非要比的話,得這樣寫:

復(fù)制代碼 代碼如下:
fb = foo.bar
Fb = Foo.bar
print id(fb) == id(Fb)

即把兩個(gè)表達(dá)式的結(jié)果綁定到名字上,再來比是不是同一個(gè)對(duì)象,你才能得到正確的結(jié)果。

is表達(dá)式也是一樣的,你現(xiàn)在得到了正確的結(jié)果,完全是因?yàn)?CPython 現(xiàn)在的實(shí)現(xiàn)細(xì)節(jié)決定的。現(xiàn)在的is的實(shí)現(xiàn),是左右兩邊的對(duì)象都計(jì)算出來,然后再比較這兩個(gè)對(duì)象的地址是否一樣。萬一哪天改成了,先算左邊,保存地址,把左邊釋放掉,再算右邊,再比較的話,你的is的結(jié)果可能就錯(cuò)了。官方文檔里也提到了這個(gè)問題 。我認(rèn)為正確的方法也是像id那樣,先把左右兩邊都計(jì)算下來,并顯式綁定到各自的名字上,然后再用is判斷。

希望本文所述對(duì)大家的Python程序設(shè)計(jì)有所幫助。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 久久av热 | 日本欧美国产精品第一页久久 | 国产精品一区三区 | 性做久久久久免费看 | 日韩不卡一区二区 | 亚洲天堂视频在线免费观看 | 色狠狠色狠狠综合天天 | 成人国产免费视频 | 国产精品自线在线播放 | 久久伊人色综合 | 成人久久18免费软件 | 日韩国产午夜一区二区三区 | 91视频青娱乐 | 日本中文字幕免费 | 无遮挡一级毛片私人影院 | 欧美精品亚洲一区二区在线播放 | 天天噜噜揉揉狠狠夜夜 | 欧美一区二区三区国产精品 | 综合久久亚洲 | 午夜影视免费 | 成人精品一区 | 成人在线精品 | 久久久成人精品视频 | 九九爱精品 | 草色在线| 激情六月丁香婷婷 | 手机成人在线视频 | 久久福利青草精品资源 | 国产成人免费精品 | 欧美鲁 | 国产成人一区二区三区 | 五月天婷婷免费观看视频在线 | 亚洲伦理在线 | 日本不卡免费新一二三区 | 久草色在线 | 国产成人精品一区二区三区四区 | 米奇影院7777| 91精品国产高清一区二区三区 | 精品国产乱码久久久久久丨区2区 | 成人性视频免费网站 | 香港全黄一级毛片在线播放 |