次の間に違いはありますか:
if foo is None: pass
と
if foo == None: pass
ほとんどの Python コード (および私自身が書いたコード) で見た規則は前者ですが、最近、後者を使用するコードに出くわしました。None は NoneType のインスタンス (および唯一のインスタンス、IIRC) であるため、問題にはなりませんよね? その可能性のある状況はありますか?
次の間に違いはありますか:
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と評価できます。空のコンテナ、ブール値など、ブール値テストでfalseを表すものがいくつかあります。この状況でfalseと評価されるものはありませんが、他のことも同様です。
(ob1 is ob2)
に等しい(id(ob1) == id(ob2))
その理由foo is None
は、独自の を定義し、その__eq__
オブジェクトが None と等しくなるように定義するオブジェクトを処理している可能性があるためです。foo is None
したがって、それが infact かどうかを確認する必要がある場合は、常に使用してくださいNone
。
同一のオブジェクトはもちろん等しいため、違いはありません。ただし、PEP 8では、以下を使用する必要があると明確に述べられていますis
。
None のようなシングルトンとの比較は、常に is または is not で行う必要があり、等値演算子では決して行わないでください。
is
平等ではなく、同一性をテストします。statementfoo 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 がブール値 (つまり 0 または 1) を本当に表さない限り、"if foo:" を使用するのは好きではありません。foo が文字列、オブジェクト、またはその他の場合、「if foo:」が機能する可能性がありますが、私には怠惰なショートカットのように見えます。x が None かどうかを確認する場合は、「if x is None:」と言います。
詳細:
この句は、2 つの が同じメモリ位置にあるis
かどうかを実際にチェックします。object
つまり、両方が同じメモリ位置を指しており、同じid
.
1 の結果として、字句的に表現された 2 つの s が同一の属性 (attributes-of-attributes...) を持つis
かどうかを保証します。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
は、最高です。