「foo is None」と「foo == None」の間に違いはありますか?
-
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:」と言います。
さらに詳しい情報:
の
is
句は実際に 2 つが一致するかどうかをチェックします。object
Sは同じメモリの場所にあるかどうかです。つまり、どちらも同じメモリの位置を指していて、同じものを持っているかどうかid
.1の結果として、
is
2 つが語彙的に表現されているかどうかを保証します。object
同一の属性 (属性の属性...) があるかどうか次のようなプリミティブ型のインスタンス化
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