簡體   English   中英

'is' 關鍵字是如何在 Python 中實現的?

[英]How is the 'is' keyword implemented in Python?

... is關鍵字可用於字符串中的相等性。

>>> s = 'str'
>>> s is 'str'
True
>>> s is 'st'
False

我嘗試了__is__()__eq__()但它們沒有用。

>>> class MyString:
...   def __init__(self):
...     self.s = 'string'
...   def __is__(self, s):
...     return self.s == s
...
>>>
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work
False
>>>
>>> class MyString:
...   def __init__(self):
...     self.s = 'string'
...   def __eq__(self, s):
...     return self.s == s
...
>>>
>>> m = MyString()
>>> m is 'ss'
False
>>> m is 'string' # <--- Expected to work, but again failed
False
>>>

與測試字符串is只有當字符串實習工作。 除非你真的知道你在做什么,明確實習,你應該使用的字符串is在字符串。

is身份測試,而不是平等測試。 這意味着Python的只是一個對象駐留比較的內存地址英寸is基本上回答這個問題:“我必須為同一對象兩個人的名字?” - 超載是沒有意義的。

例如, ("a" * 100) is ("a" * 100)False 通常 Python 將每個字符串寫入不同的內存位置,實習主要發生在字符串文字中。

is運算符等效於比較id(x)值。 例如:

>>> s1 = 'str'
>>> s2 = 'str'
>>> s1 is s2
True
>>> id(s1)
4564468760
>>> id(s2)
4564468760
>>> id(s1) == id(s2)  # equivalent to `s1 is s2`
True

id當前實現為使用指針作為比較。 所以你不能重載is本身,AFAIK 你也不能重載id

所以,你不能。 在 python 中不尋常,但它確實存在。

Python is關鍵字測試對象身份。 您不應該使用它來測試字符串是否相等。 它似乎經常工作,因為 Python 實現,就像許多非常高級的語言一樣,執行字符串的“實習”。 也就是說,字符串文字和值在內部保存在一個散列列表中,而那些相同的將呈現為對同一對象的引用。 (這是可能的,因為 Python 字符串是不可變的)。

但是,與任何實現細節一樣,您不應依賴於此。 如果要測試相等性,請使用 == 運算符。 如果你真的想測試對象身份,那么使用is --- 我很難想出一個你應該關心字符串對象身份的情況。 不幸的是,由於上述實習,您不能指望兩個字符串是否以某種方式“故意”相同的對象引用。

is關鍵字比較對象(或者更確切地說,比較兩個引用是否指向同一個對象)。

我認為,這就是為什么沒有提供您自己的實現的機制。

它碰巧有時對字符串起作用,因為 Python 會“巧妙地”存儲字符串,因此當您創建兩個相同的字符串時,它們會存儲在一個對象中。

>>> a = "string"
>>> b = "string"
>>> a is b
True
>>> c = "str"+"ing"
>>> a is c
True

您可以在一個簡單的“復制”示例中看到參考與數據的比較:

>>> a = {"a":1}
>>> b = a
>>> c = a.copy()
>>> a is b
True
>>> a is c
False

如果你不怕弄亂字節碼,你可以用8 ("is")參數攔截和修補COMPARE_OP以在被比較的對象上調用你的鈎子函數。 查看dis模塊文檔以了解開始。

如果有人會做id(a) == id(b)而不是a is b ,也不要忘記攔截__builtin__.id()

'is' 比較對象標識,而 == 比較值。

例子:

a=[1,2]
b=[1,2]
#a==b returns True
#a is b returns False

p=q=[1,2]
#p==q returns True
#p is q returns True

當字符串以“-”開頭時,無法將字符串變量與字符串值和兩個字符串變量進行比較。 我的 Python 版本是 2.6.6

>>> s = '-hi'
>>> s is '-hi'
False 
>>> s = '-hi'
>>> k = '-hi'
>>> s is k 
False
>>> '-hi' is '-hi'
True

您正在使用身份比較。 ==可能就是你想要的。 例外情況是,當您想要檢查一個項目和另一個項目是否是完全相同的對象並且在相同的內存位置時。 在您的示例中,項目不相同,因為一個類型 (my_string) 與另一個類型 (string) 不同。 此外,沒有像 someclass 這樣的東西。 __is__在 python 中(當然,除非你自己把它放在那里)。 如果有,將對象與is進行簡單比較不可靠的。

當我第一次遇到is關鍵字時,它也讓我感到困惑。 我會認為is和 == 沒有什么不同。 他們從解釋器對許多對象產生了相同的輸出。 這種類型的假設實際上是究竟什么?是。 這是蟒蛇的等價物“嘿,不要誤會這兩個對象。它們是不同的。”,這基本上就是[無論是誰讓我理直氣壯]所說的。 措辭大不相同,但一點==另一點。

有關一些有用的示例和一些有助於解決有時令人困惑的差異的文本,請訪問由“Danny Yoo”編寫的 來自 python.org 郵件主機的文檔

或者,如果它處於離線狀態,請使用我用它的身體制作的未列出的 pastebin

如果它們在大約 20 個左右的藍月亮(藍月亮是真實事件)中都出現故障,我將引用代碼示例

###
>>> my_name = "danny"
>>> your_name = "ian"
>>> my_name == your_name
0                #or False
###

###
>>> my_name[1:3] == your_name[1:3]
1    #or True
###

###
>>> my_name[1:3] is your_name[1:3]
0
###

您不能重載is運算符。 您要重載的是==運算符。 這可以通過在類中定義__eq__方法來完成。

在比較對象時,使用is關鍵字很容易出現斷言錯誤。 例如,對象ab可能持有相同的值並共享相同的內存地址。 因此,做一個

>>> a == b

將評估為

True

但是如果

>>> a is b

評估為

False

你應該檢查一下

>>> type(a)

>>> type(b)

這些可能是不同的,也是失敗的原因。

因為字符串實習,這可能看起來很奇怪:

a = 'hello'
'hello' is a  #True

b= 'hel-lo'
'hel-lo' is b #False

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM