68

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

11 に答える 11

141

文字列のテストisは、文字列がインターンされている場合にのみ機能します。自分が何をしているのかを本当に理解していて、文字列を明示的にインターンしていない限り、文字列には決して使用isしないでください。

is同等性ではなく同一性をテストします。つまり、Python はオブジェクトが存在するメモリ アドレスを単純に比較します。基本的には、「同じオブジェクトに 2 つの名前がありますか?」という質問に答えます。-意味をなさない過負荷。is

たとえば、False("a" * 100) is ("a" * 100)です。通常、Python は各文字列を異なるメモリ位置に書き込みます。インターンは主に文字列リテラルに対して行われます。

于 2010-06-07T08:21:44.777 に答える
24

演算子は値の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、それ自体をオーバーロードすることはできません。また、知る限り、オーバーロードすることもできませんid

だから、できません。Pythonでは珍しいですが、あります。

于 2010-06-07T08:27:04.423 に答える
16

Pythonisキーワードは、オブジェクトの同一性をテストします。文字列が等しいかどうかをテストするために使用しないでください。Python の実装は、多くの非常に高度な言語の実装と同様に、文字列の「インターニング」を実行するため、頻繁に機能するように見えるかもしれません。つまり、文字列リテラルと値は内部的にハッシュされたリストに保持され、同一のものは同じオブジェクトへの参照としてレンダリングされます。(これは、Python 文字列が不変であるため可能です)。

ただし、実装の詳細と同様に、これに依存するべきではありません。等しいかどうかをテストする場合は、== 演算子を使用します。本当にオブジェクト ID をテストしたい場合は、is--- を使用してください。文字列オブジェクト ID を気にする必要があるケースを思いつくのは難しいでしょう。残念ながら、前述のインターンのために、2 つの文字列が「意図的に」同一のオブジェクト参照であるかどうかを当てにすることはできません。

于 2010-06-07T08:27:41.927 に答える
10

このisキーワードは、オブジェクトを比較します (または、2 つの参照が同じオブジェクトへの参照であるかどうかを比較します)。

これが、独自の実装を提供するメカニズムがない理由だと思います。

Python は文字列を「巧妙に」保存するため、文字列に対して時々機能することがあります。2 つの同一の文字列を作成すると、それらは 1 つのオブジェクトに保存されます。

>>> 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
于 2010-06-07T08:26:21.897 に答える
5

バイトコードを台無しにすることを恐れていない場合は、引数をインターセプトしてパッチCOMPARE_OPを適用し8 ("is")、比較対象のオブジェクトに対してフック関数を呼び出すことができます。dis開始については、モジュールのドキュメントを参照してください。

__builtin__.id()そして、誰かがid(a) == id(b)の代わりに行う場合は、傍受することも忘れないでくださいa is b

于 2010-10-12T03:03:09.417 に答える
2

文字列が「-」で始まる場合、文字列変数を文字列値および 2 つの文字列変数と比較できません。私のPythonバージョンは2.6.6です

>>> s = '-hi'
>>> s is '-hi'
False 
>>> s = '-hi'
>>> k = '-hi'
>>> s is k 
False
>>> '-hi' is '-hi'
True
于 2011-04-07T15:53:34.977 に答える
1

is演算子をオーバーロードすることはできません。オーバーロードしたいのは==演算子です。__eq__これは、クラスでメソッドを定義することで実行できます。

于 2011-06-15T04:24:14.287 に答える
1

ID 比較を使用しています。==はおそらくあなたが望むものです。これに対する例外は、あるアイテムと別のアイテムがまったく同じオブジェクトであり、同じメモリ位置にあるかどうかを確認したい場合です。あなたの例では、一方が他方 (string) とは異なるタイプ (my_string) であるため、アイテムは同じではありません。また、someclass というものはありません。__is__Pythonで(もちろん、自分で配置しない限り)。存在する場合、オブジェクトをisと比較しても、単にメモリの場所を比較するだけでは信頼できません。

最初にisキーワードに遭遇したとき、私も混乱しました。isと == は変わらないと思っていたでしょう。それらは、多くのオブジェクトでインタープリターから同じ出力を生成しました。このタイプの仮定は、実際には正確に...の目的です。これは、python に相当する「ねえ、これらの 2 つのオブジェクトを間違えないでください。それらは異なります。」、これは本質的に [私を正した人は誰でも] 言ったことです。言い方はかなり異なりますが、1 つのポイント == もう 1 つのポイントです。

「Danny Yoo」によって書かれたpython.orgのメール ホストのドキュメントを参照してください。

または、それがオフラインの場合は、その本体で作成したリストにないペーストビンを使用します。

約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
###
于 2013-01-04T18:01:53.867 に答える