是運算符比較兩個對象的內存地址是否相同,則返回true否則返回false。 代碼#1是運算符混淆
>>a="poi"
>>b="poi"
a is b
true
我已經創建了兩個對象,其內容是相同的,但它們是在不同的內存地址的整個生活。 那麼爲什麼操作符返回true?它不應該返回錯誤。 就像這個代碼
>>ktr = "today is a fine day"
>>ptr = "today is a fine day"
>>ktr is ptr
false
是運算符比較兩個對象的內存地址是否相同,則返回true否則返回false。 代碼#1是運算符混淆
>>a="poi"
>>b="poi"
a is b
true
我已經創建了兩個對象,其內容是相同的,但它們是在不同的內存地址的整個生活。 那麼爲什麼操作符返回true?它不應該返回錯誤。 就像這個代碼
>>ktr = "today is a fine day"
>>ptr = "today is a fine day"
>>ktr is ptr
false
我認爲它與string interning.有關。本質上,其思想是僅存儲每個不同字符串的單個副本,以提高某些操作的性能。
基本上,a is b
工作的原因是因爲(正如您可能已經猜到的那樣),在這兩種情況下都有Python引用的單個不可變字符串。當一個字符串很大(以及其他一些我不明白的因素時,很可能),這不會完成,這就是爲什麼您的第二個示例返回False。
編輯:而事實上,奇怪的行爲似乎是互動環境的副作用。如果您將相同的代碼放入Python腳本中,則a is b
和ktr is ptr
都會返回True。
a="poi"
b="poi"
print a is b # Prints 'True'
ktr = "today is a fine day"
ptr = "today is a fine day"
print ktr is ptr # Prints 'True'
這很有道理,因爲Python可以很容易地解析源文件並在其中查找重複的字符串文字。如果您動態創建字符串,則即使在腳本中它的行爲也不同。
a="p" + "oi"
b="po" + "i"
print a is b # Oddly enough, prints 'True'
ktr = "today is" + " a fine day"
ptr = "today is a f" + "ine day"
print ktr is ptr # Prints 'False'
至於爲什麼a is b
仍然導致真,也許分配的字符串足夠小,以保證通過實習集合的快速搜索,而另一種是不?
關於'a =「p」+「oi」; b =「po」+「i」',編譯器通過在代碼對象中存儲兩個對''poi''的引用來優化簡單字符串連接,這些引用被放置在適當位置。 ''今天是一個美好的一天「'因爲它包含空格(即非名字符)而沒有被實施。 – eryksun
is
是身份鑑定。它將工作在更小的某些字符串(因爲緩存)而不是更大的其他字符串。由於str不是ptr。 [感謝erykson]
參見此代碼:
>>> import dis
>>> def fun():
... str = 'today is a fine day'
... ptr = 'today is a fine day'
... return (str is ptr)
...
>>> dis.dis(fun)
2 0 LOAD_CONST 1 ('today is a fine day')
3 STORE_FAST 0 (str)
3 6 LOAD_CONST 1 ('today is a fine day')
9 STORE_FAST 1 (ptr)
4 12 LOAD_FAST 0 (str)
15 LOAD_FAST 1 (ptr)
18 COMPARE_OP 8 (is)
21 RETURN_VALUE
>>> id(str)
26652288
>>> id(ptr)
27604736
#hence this comparison returns false: ptr is str
通知str
和ptr
的ID不同。
BUT:x和y的
>>> x = "poi"
>>> y = "poi"
>>> id(x)
26650592
>>> id(y)
26650592
#hence this comparison returns true : x is y
ID相同。因此,is
運算符工作在「ids」而不是「equalities」上
請參閱下面的鏈接,瞭解python何時和爲什麼會爲相同的字符串分配不同的內存位置(也請閱讀該問題)。在python2.x
When does python allocate new memory for identical strings
而且sys.intern
上python3.x和intern
應該幫助你分配的字符串相同的內存位置,該字符串的大小無關。
is
是不是與==
相同。
基本上,is
檢查兩個對象是否相同,而==
比較這些對象(字符串,如python中的所有內容,都是對象)的值。
所以你應該使用is
當你真的知道你正在看什麼對象(即你已經做出了對象,或者正在與None
作爲問題評論指出)比較,你想知道是否兩個變量在內存中引用完全相同的對象。
然而,在您的示例中,您正在查看Python正在幕後處理的str
對象,因此,如果不深入研究python的工作原理,您就不會真正瞭解期望的結果。您會遇到與int
s或float
s相同的問題。其他答案在解釋「幕後」內容(字符串實習)方面做得很好,但在日常編程中你大多不應該擔心。
那麼爲什麼這兩個例子不同呢?這不解釋。 – agf
@agf剛剛編輯 - 這是否解釋我的意思是我的回答更好? –
請注意,這是CPython特定的優化。如果你想要你的代碼是可移植的,你應該避免它。例如,在PyPy
>>>> a = "hi"
>>>> b = "hi"
>>>> a is b
False
另外值得指出的是,類似的事情發生了小整數
>>> a = 12
>>> b = 12
>>> a is b
True
再次你不應該依賴,因爲其他的實現可能不包含這種優化。
在實踐中,除非你正在做一些相當複雜的事情,否則你可能永遠不會使用'is'。大概需要'=='來進行大多數的相等比較。 – dkamins
@dkamins:測試'None'的推薦方法是'':'some_var是None'(因爲只有一個'None'的實例)。我會說這是一個很常見的情況。 – voithos
@voithos真的 - 我一直都在使用它(而不是'''),甚至沒有想到它!但除此之外...... – dkamins