>>> a = ['spam']
>>> b = ['spam']
>>> a is b
False
參考:
>>> c = ['spam']
>>> d = c
>>> c is d
True
- 是什麼都上方的區別?
- 爲什麼分配結果
False
? - 爲什麼參考結果
True
?
>>> a = ['spam']
>>> b = ['spam']
>>> a is b
False
參考:
>>> c = ['spam']
>>> d = c
>>> c is d
True
False
?True
?您的第一個片段創建了兩個唯一的列表對象,它們是不一樣的。因此a is b
返回false,因爲a
和b
都指向不同的對象:
+------+ a ------> | list | +------+ +------+ b ------> | list | +------+
你的第二個片斷創建一個列表對象,並分兩個c
和d
到對象,因此c is d
返回true:
+------+ c ------> | list | <------ d +------+
請注意以下,從http://docs.python.org/3/reference/datamodel.html:
每個對象都有一個標識,一個類型和一個值。對象的標識一旦創建就永不改變;你可能會認爲它是內存中的對象地址。
is
運算符比較兩個對象的標識;id()
函數返回一個表示其身份的整數。
所以is
和==
是非常不同的;而前者比較對象身份,後者比較對象的值。實際上,==
測試在您的片段中將返回true。
鑑於上述的解釋,它可能會作爲一個驚喜,這個故事是用繩子略有不同:
>>> a = 'str'
>>> b = 'str'
>>>
>>> a is b
True
這是由於string interning,發生在CPython的(也就是說,它的具體實現)。因此,如果相同的字符串文字在兩個不同的位置出現,則兩個(有限制)將使用相同的字符串對象。
這在"Python string interning"中有更詳細的解釋。
讓我只是添加一些函數調用到你原來的工作。我想你會選擇它。
>>> a = ['spam']
>>> b = ['spam']
>>> a is b
False
>>> id(a)
4552359808
>>> id(b)
4552446176
>>> a == b
True
>>> c = ['spam']
>>> d = c
>>> id(c)
4552513296
>>> id(d)
4552513296
>>> c is d
True
>>> c == d
True
>>> print id.__doc__
id(object) -> integer
Return the identity of an object. This is guaranteed to be unique among
simultaneously existing objects. (Hint: it's the object's memory address.)
時is
比較,像a is b
,這是一樣的id(a) == id(b)
,代碼xx=['spam']
創建一個新的列表中的每個時間並將其分配給xx
,它的id
每次都有改變,因此a is b
給假
這與一些(不存在的)「賦值與引用」問題無關。
>>> a = ['spam']
創建一個包含字符串'spam'的列表,並將其綁定到當前作用域中的名稱'a'。
>>> b = ['spam']
用字符串'spam'創建另一個列表,並將其綁定到當前作用域中的名稱'b'。
您創建兩個列表,您有兩個列表。平原簡單。
>>> c = ['spam']
創建另一個帶有字符串'spam'的列表,並將其綁定到當前作用域中的名稱'c'。
>>> d = c
將名稱'd'綁定到當前在當前範圍內綁定的任何'c'。
在這裏,您創建一個列表併爲其綁定2個名稱。兩個名字都指向同一個對象。
問題是:Python的「變量」沒有命名爲內存地址,只是名稱指向對象。在給定時間,一個對象可以綁定(指向)任意數量的名稱(甚至根本沒有名字)。
+1爲ASCII藝術: – thefourtheye
因此,如果我嘗試在不變的對象,如str「spam」而不是列表「'['spam']上面,爲什麼兩者的結果都是」True「 '' –
@YousufMemon這是因爲[字符串在CPython中執行](http://stackoverflow.com/questions/15541404/python-string-interning)。 – arshajii