2014-01-13 42 views
2

分配:參考VS分配在Python可變對象

>>> a = ['spam'] 
>>> b = ['spam'] 
>>> a is b 
False 

參考:

>>> c = ['spam'] 
>>> d = c 
>>> c is d 
True 
  1. 是什麼都上方的區別?
  2. 爲什麼分配結果False
  3. 爲什麼參考結果True

回答

9

您的第一個片段創建了兩個唯一的列表對象,它們是不一樣的。因此a is b返回false,因爲ab都指向不同的對象:

 
      +------+ 
a ------> | list | 
      +------+ 

      +------+ 
b ------> | list | 
      +------+ 

你的第二個片斷創建一個列表對象,並分兩個cd到對象,因此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"中有更詳細的解釋。

+0

+1爲ASCII藝術: – thefourtheye

+0

因此,如果我嘗試在不變的對象,如str「spam」而不是列表「'['spam']上面,爲什麼兩者的結果都是」True「 '' –

+1

@YousufMemon這是因爲[字符串在CPython中執行](http://stackoverflow.com/questions/15541404/python-string-interning)。 – arshajii

1

讓我只是添加一些函數調用到你原來的工作。我想你會選擇它。

>>> 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.) 
4

is比較,像a is b,這是一樣的id(a) == id(b),代碼xx=['spam']創建一個新的列表中的每個時間並將其分配給xx,它的id每次都有改變,因此a is b

2

這與一些(不存在的)「賦值與引用」問題無關。

>>> a = ['spam'] 

創建一個包含字符串'spam'的列表,並將其綁定到當前作用域中的名稱'a'。

>>> b = ['spam'] 

用字符串'spam'創建另一個列表,並將其綁定到當前作用域中的名稱'b'。

您創建兩個列表,您有兩個列表。平原簡單。

>>> c = ['spam'] 

創建另一個帶有字符串'spam'的列表,並將其綁定到當前作用域中的名稱'c'。

>>> d = c 

將名稱'd'綁定到當前在當前範圍內綁定的任何'c'。

在這裏,您創建一個列表併爲其綁定2個名稱。兩個名字都指向同一個對象。

問題是:Python的「變量」沒有命名爲內存地址,只是名稱指向對象。在給定時間,一個對象可以綁定(指向)任意數量的名稱(甚至根本沒有名字)。