Pythonなしの比較:「is」または==を使用する必要がありますか?


212

比較するmy_var == Noneと警告が表示されますが、使用すると警告は表示されませんmy_var is None

私はPythonシェルでテストを行い、両方が有効な構文であることを確認しましたが、私のエディターはそれmy_var is Noneが望ましいと言っているようです。

これは事実ですか、もしそうなら、なぜですか?


7
PEP 8は、使用してシングルトンと比較すべきであることをどこかで述べているis- python.org/dev/peps/pep-0008/#programming-recommendations
ボラティリティ

2
そのポスターはPython 3について話しており、私の質問はPython 2.xについてです。これが残りの両方を保証するのに十分な大きさの違いであるかどうかはわかりませんが、念のために質問を編集して含めました。
Clay Wardell 2013年

2
この質問は本当に重複しているとは思いません。もう1つは==についてでしたvsは一般的に、これは特にNoneについてです。
IJケネディ

回答:


254

概要:

使用isあなたは、オブジェクトのに対してチェックしたいアイデンティティ(例えばかどうかをチェックvarですNone)。使用==を確認したい平等を(例えばですvarに等しいです3?)。

説明:

あなたmy_var == Noneは戻るカスタムクラスを持つことができますTrue

例えば:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isオブジェクトの同一性をチェックします。オブジェクトは1つしかないNoneため、を実行するとmy_var is None、それらが実際に同じオブジェクトであるかどうかを確認します(同等のオブジェクトだけではありません)。

言い換えると、==は等価性のチェック(オブジェクト間で定義されます)に対してis、オブジェクトの同一性をチェックします。

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
とはいつis None違います== Noneか?
Blender

11
@ブレンダー上記の場合。__eq__どのように定義することもできますが、の動作をis簡単に変更することはできません。
Lev Levitsky 2013年

5
@LevLevitsky:Mythonの使用例の1つは、「プロトコルを拡張して、どんなオペレーターでも過負荷にできるようにするis」ことでした。リストについてのコメントの後で、彼はそれを「… is(ただし、あなたが正気でない場合のみ)」に変更しました。
abarnert 2013年

1
+1ですが、この回答に他の人が行うPEP 8のリファレンスが含まれていると(さらに、PEP 8の背後にある決定が理にかなっている理由を説明しているので、すでにそうです)、さらに良いでしょう。
abarnert 2013年

3
@abarnert-PEP 8がここで推奨することを私も知らなかった。ポイントは、それらが異なることをする異なるオペレーターであるということです。object == None実際に正しいイディオムである場合があります(ただし、頭のてっぺんから考えることはできません)。あなたは自分が何をしているかを知る必要があるだけです。
mgilson 2013年

127

is任意オブジェクトをシングルトンと比較する場合などNoneは、より高速で予測可能であるため、一般的に推奨されます。is常にオブジェクトIDで比較しますが、何==が行われるかは、オペランドの正確なタイプとその順序にも依存します。

この推奨事項はPEP 8でサポートされおり、「Noneのようなシングルトンとの比較は常にisor is notで行う必要があります。


6
これを投稿していただきありがとうございます。受け入れられた回答にはいくつか興味深い点がありますが、あなたの回答はより直接的に質問に答えます。
ルーク・デイビス

本質的に実装の詳細であるものに依存するのは奇妙に思えます。NoneTypeのインスタンスがいくつあるか気にする必要があるのはなぜですか?
BallpointBen

@BallpointBenこれは実装の詳細ではないためNone、グローバル定数の下にはオ​​ブジェクトが1つしかありませんNone。どちらかと言えばNoneTypeNoneシングルトンは何らかのタイプを持たなければならないので、これは実装の詳細です。(このタイプのインスタンスを作成できないという事実は、その1つのインスタンスがシングルトンであることが意図されていることを示しています。)
user4815162342

@BallpointBen重要なポイントは、Pythonにはオブジェクトアイデンティティの強力なコンセプトがあることだと思います。オブジェクトがと等しいかどうかを確認する場合None、必ずを使用してくださいobj == None。オブジェクト かどうかを確認する場合None、を使用しますobj is None。PEP 8の推奨事項(およびこの回答)の要点は、ほとんどの人がNoneをチェックするときに後者を必要とすることであり、それはたまたに速くて明確です。
user4815162342

Noneまた、などのキャッシュされたオブジェクト0や他の小さな整数とは異なります。キャッシュは実際には実装の詳細です。違いは、整数には固有の値があり、そのプロパティを与え、計算できることです。一方、None状態はまったくなく、重要であり、それを特別にするのはそのアイデンティティだけです。
user4815162342

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.