「foo is None」と「foo == None」の間に違いはありますか?

StackOverflow https://stackoverflow.com/questions/26595

  •  09-06-2019
  •  | 
  •  

質問

以下の間に違いはありますか?

if foo is None: pass

そして

if foo == None: pass

私がこれまでに見たほとんどの Python コード (および私自身が作成するコード) で見られる規則は前者ですが、最近、後者を使用するコードに遭遇しました。None は NoneType のインスタンス (そして唯一のインスタンス IIRC) なので、問題ではないはずですよね。そうなる可能性がある状況はありますか?

役に立ちましたか?

解決

is 常に戻ってきます True 同じオブジェクトインスタンスを比較する場合

一方 == 最終的には __eq__() 方法

つまり


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

他のヒント

これを読んでみてはいかがでしょうか オブジェクトの同一性と等価性.

ステートメント「is」はオブジェクトの識別に使用され、オブジェクトが同じインスタンス (メモリ内の同じアドレス) を参照しているかどうかをチェックします。

そして、「==」ステートメントは等しい(同じ値)を指します。

注意事項:

if foo:
  # do something

ない 以下とまったく同じです:

if x is not None:
  # do something

前者はブール値テストであり、さまざまなコンテキストで false と評価される可能性があります。ブール値テストでは、空のコンテナーやブール値など、偽を表すものが数多くあります。この状況では None も false と評価されますが、他のものも同様に false と評価されます。

(ob1 is ob2) に等しい (id(ob1) == id(ob2))

理由 foo is None 推奨される方法は、独自に定義するオブジェクトを処理する可能性があることです。 __eq__, 、そしてそれはオブジェクトがNoneに等しいと定義します。したがって、常に使用してください foo is None それが事実かどうかを確認する必要がある場合 None.

同一のオブジェクトは当然等しいので、違いはありません。しかし、 PEP8 使用する必要があることを明確に示しています is:

None のようなシングルトンとの比較は、常に is または is not を使用して実行する必要があり、決して等価演算子を使用しないでください。

is 身元を確認するテスト、 ない 平等。あなたの声明に対して foo is none, Python は単純にオブジェクトのメモリアドレスを比較します。これは、「同じオブジェクトに 2 つの名前がありますか?」という質問をしていることを意味します。

== 一方、によって決定される平等性をテストします。 __eq__() 方法。それはアイデンティティを気にしません。

In [102]: x, y, z = 2, 2, 2.0

In [103]: id(x), id(y), id(z)
Out[103]: (38641984, 38641984, 48420880)

In [104]: x is y
Out[104]: True

In [105]: x == y
Out[105]: True

In [106]: x is z
Out[106]: False

In [107]: x == z
Out[107]: True

None シングルトン演算子です。それで None is None は常に真実です。

In [101]: None is None
Out[101]: True

None の場合、等価 (==) と同一性 (is) の間に違いがあってはなりません。NoneType はおそらく等しい場合に ID を返します。None は NoneType で作成できる唯一のインスタンスであるため (これは真実だと思います)、2 つの操作は同じです。他のタイプの場合、これは必ずしも当てはまるとは限りません。例えば:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

リストにはデフォルトで返される ID ではない比較演算があるため、これは「Equal」を出力します。

@ジェイソン:

次のようなものを使用することをお勧めします

if foo:
    #foo isn't None
else:
    #foo is None

私は、foo が本当にブール値を表す場合を除いて、「if foo:」を使用するのは好きではありません(つまり、0 または 1)。foo が文字列、オブジェクト、またはその他のものである場合、「if foo:」は機能する可能性がありますが、私にとっては怠惰なショートカットのように見えます。x が None かどうかを確認する場合は、「if x is None:」と言います。

さらに詳しい情報:

  1. is 句は実際に 2 つが一致するかどうかをチェックします。 objectSは同じメモリの場所にあるかどうかです。つまり、どちらも同じメモリの位置を指していて、同じものを持っているかどうか id.

  2. 1の結果として、 is 2 つが語彙的に表現されているかどうかを保証します。 object同一の属性 (属性の属性...) があるかどうか

  3. 次のようなプリミティブ型のインスタンス化 bool, int, string(一部を除く)、 NoneType 同じ値を持つものは常に同じメモリ位置にあります。

例えば。

>>> int(1) is int(1)
True
>>> str("abcd") is str("abcd")
True
>>> bool(1) is bool(2)
True
>>> bool(0) is bool(0)
True
>>> bool(0)
False
>>> bool(1)
True

それ以来 NoneType Python の「ルックアップ」テーブルにはそれ自体のインスタンスが 1 つしか存在できないため、前者と後者はどちらかを選択する微妙な論理的理由があるというよりは、コードを書いた開発者のプログラミング スタイル (おそらく一貫性のため) です。もう一方の上に。

ジョン・マチンの結論は、 None シングルトンであるという結論は、このコードによって裏付けられます。

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

以来 None シングルトンです、 x == None そして x is None 同じ結果になります。しかし、私の美学的な意見では、 x == None 最高です。

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top