1. ホーム
  2. python

[解決済み] Pythonで「if not someobj:」が「if someobj == None:」より優れているのはなぜですか?

2022-05-12 10:38:53

質問

このようなコードの例をいくつか見たことがあります。

if not someobj:
    #do something

でも、なぜやらないのか不思議です。

if someobj == None:
    #do something

何か違いがあるのでしょうか?どちらかに優位性があるのでしょうか?

どのように解決するのですか?

最初のテストでは、Pythonはオブジェクトを bool の値がない場合は、その値を使用します。大雑把に言うと 私たちは、対象物に「あなたは意味があるのですか、ないのですか」と尋ねているのです。 これは、以下のアルゴリズムで行われます。

  1. オブジェクトが __nonzero__ 特別なメソッド(数値組み込みのように。 intfloat ) の場合、このメソッドを呼び出します。このメソッドは bool の値を直接使用するか、あるいは int とみなされる値 False がゼロの場合。

  2. そうでない場合、オブジェクトに __len__ 特殊なメソッド(コンテナ内蔵型もそうです。 list , dict , set , tuple というコンテナを考えて、このメソッドを呼び出します。 False が空である場合(長さが0である場合)。

  3. それ以外の場合は、オブジェクトは True でない限り None と見なされ、その場合は False .

2つ目のテストでは、オブジェクトが以下のものと等しいかどうかを比較します。 None . ここで と尋ねているのです。 これは、次のアルゴリズムを使って行われます。

  1. オブジェクトが __eq__ メソッドが呼び出され、その戻り値が bool の結果を決定するために使用されます。 if .

  2. そうでない場合、オブジェクトに __cmp__ メソッドが呼び出されます。この関数は int の順序を示す2つのオブジェクト( -1 もし self < other , 0 もし self == other , +1 もし self > other ).

  3. そうでない場合は、オブジェクトの同一性 (つまり、同じオブジェクトへの参照であるかどうか) が比較され、これは is 演算子)。

を使った別のテストも可能です。 is 演算子を使用します。 このオブジェクトに対して、「あなたはこの特定のオブジェクトですか?

一般的に、数値以外の値では最初のテストを使い、同じ性質のオブジェクト(2つの文字列、2つの数値、...)を比較したいときには等質性のテストを使い、センチネル値( None の意味は、例えばメンバ・フィールドが初期化されていない場合、あるいは getattr または __getitem__ メソッド) を使用します。

要約すると、:

>>> class A(object):
...    def __repr__(self):
...        return 'A()'
...    def __nonzero__(self):
...        return False

>>> class B(object):
...    def __repr__(self):
...        return 'B()'
...    def __len__(self):
...        return 0

>>> class C(object):
...    def __repr__(self):
...        return 'C()'
...    def __cmp__(self, other):
...        return 0

>>> class D(object):
...    def __repr__(self):
...        return 'D()'
...    def __eq__(self, other):
...        return True

>>> for obj in ['', (), [], {}, 0, 0., A(), B(), C(), D(), None]:
...     print '%4s: bool(obj) -> %5s, obj == None -> %5s, obj is None -> %5s' % \
...         (repr(obj), bool(obj), obj == None, obj is None)
  '': bool(obj) -> False, obj == None -> False, obj is None -> False
  (): bool(obj) -> False, obj == None -> False, obj is None -> False
  []: bool(obj) -> False, obj == None -> False, obj is None -> False
  {}: bool(obj) -> False, obj == None -> False, obj is None -> False
   0: bool(obj) -> False, obj == None -> False, obj is None -> False
 0.0: bool(obj) -> False, obj == None -> False, obj is None -> False
 A(): bool(obj) -> False, obj == None -> False, obj is None -> False
 B(): bool(obj) -> False, obj == None -> False, obj is None -> False
 C(): bool(obj) ->  True, obj == None ->  True, obj is None -> False
 D(): bool(obj) ->  True, obj == None ->  True, obj is None -> False
None: bool(obj) -> False, obj == None ->  True, obj is None ->  True