不思議なことに:
_>>> a = 123
>>> b = 123
>>> a is b
True
>>> a = 123.
>>> b = 123.
>>> a is b
False
_
_a is b
_は多かれ少なかれid(a) == id(b)
として定義されているようです。この方法でバグを作成するのは簡単です。
_basename, ext = os.path.splitext(fname)
if ext is '.mp3':
# do something
else:
# do something else
_
一部のfnameは、予期せずelseブロックになりました。修正は簡単です。代わりに_ext == '.mp3'
_を使用する必要がありますが、それでも、表面上の_if ext is '.mp3'
_は、これを書くための優れたPythonの方法のようであり、「正しい」方法よりも読みやすくなっています。
文字列は不変なので、なぜそれが間違っているのかについての技術的な詳細は何ですか?アイデンティティチェックはいつより良くなり、同等性チェックはいつより良くなりますか?
私の知る限り、is
はオブジェクトIDの同等性をチェックします。強制的な「文字列インターン」がないため、たまたま同じ文字が順番に並んでいる2つの文字列は、通常、同じ文字列オブジェクトではありません。
文字列から部分文字列(または実際にはシーケンスから任意の部分列)を抽出すると、同じ値を含む2つの異なるオブジェクトになります。
したがって、オブジェクトIDを比較する場合にのみ、is
を使用してください。使用する ==
値を比較する場合。
それらは根本的に異なります。
==
は、__eq__
メソッドを呼び出して比較しますis
は、2つの参照が同じオブジェクトに対するものである場合にのみtrueを返しますつまり、Javaと比較して:
is
はオブジェクトの==
と同じです==
はオブジェクトのequals
と同じですPythonではisまたは==を使用するかどうかを決定するための簡単なルール
これが簡単なルールです(PythonインタープリターまたはPythonオブジェクト)で面白いことをするフレームワークを構築する)の理論に行きたくない場合は:
使用はNone
比較のみです。
if foo is None
それ以外の場合は==を使用します。
if x == 3
その後、あなたは安全な側にいます。これの理論的根拠は、上記のコメントですでに説明されています。なぜそれをするのか100%確信が持てない場合は使用しないでください。
is
をSyntaxWarning: "is" with a literal. Did you mean "=="?
などの警告付きのリテラルとともに使用すると、PyCharmによって警告されるはずです。したがって、リテラルと比較するときは、常に==
を使用してください。それ以外の場合は、参照を通じてオブジェクトを比較するためにis
を使用することをお勧めします。
APIで使用される定数のデフォルト値として使用されるこのようなクラスを定義することも役立ちます。この場合、==演算子よりも使用する方が正しいでしょう。
class Sentinel(object):
"""A constant object that does not change even when copied."""
def __deepcopy__(self, memo):
# Always return the same object because this is essentially a constant.
return self
def __copy__(self):
# called via copy.copy(x)
return self