PythonにおけるNoneの判定

Modified: | Tags: Python

PythonにおいてNoneは値が存在しないことを表す組み込み定数。Noneと判定するにはis Noneis not Noneとする。

なお、非数を表すnanは浮動小数点数float型の値でNoneとは別物。nanについての詳細は以下の記事を参照。

PythonにおけるNone

PythonにおけるNoneNoneType型のオブジェクト。

a = None
print(a)
# None

print(type(a))
# <class 'NoneType'>

値が存在しないことを表し、例えばreturnで明示的に値を返さない関数はNoneを返す。

def func_none():
    # do something
    pass

x = func_none()
print(x)
# None

Noneの判定: "is None", "is not None"

Pythonのコーディング規約PEP8で推奨されているように、ある変数がNoneであるか、Noneでないかの判定にはis None, is not Noneを使う。

None のようなシングルトンと比較をする場合は、常に isis not を使うべきです。絶対に等値演算子を使わないでください。 プログラミングに関する推奨事項 — pep8-ja 1.0 ドキュメント

a = None
print(a is None)
# True

print(a is not None)
# False

Noneはシングルトン(NoneType型の唯一のインスタンス)なので、値の比較(==, !=)は不要で、オブジェクト同一性の比較(is, is not)で判定できる。

None は単量子 (singleton) なので、オブジェクトの同一性テスト (C では ==) を使うだけで十分だからです。 None オブジェクト — Python 3.11.3 ドキュメント

==!=Noneと比較したり、変数自体をNoneでないことを表す条件式として使ったりすることは避けたほうがよい。以下、その理由を述べる。

==や!=に対するNone

==!=Noneと比較してもis, is notと同じ結果となる。

a = None
print(a == None)
# True

print(a != None)
# False

しかし、==, !=は特殊メソッド__eq__, __ne__でオーバーロード可能であり、自由にカスタマイズできる。

したがって、__eq__の実装によっては== NoneNoneでない値に対してもTrueを返す可能性がある。is Noneは常に正しく判定される。

class MyClass:
    def __eq__(self, other):
        return True

my_obj = MyClass()
print(my_obj == None)
# True

print(my_obj is None)
# False

Noneの真偽値判定

Pythonではすべてのオブジェクトが真偽値(TrueまたはFalse)として判定される。

NoneFalseと判定される。

print(bool(None))
# False

しかし、ある変数xNoneでないという条件分岐をif xと書いてはいけない。0を表す数値や空文字、空のリストなどもFalseと判定されるので、Noneと区別できない。

a = None

if a:
    print(f'{a} is not None')
else:
    print(f'{a} is None')
# None is None

a = 0

if a:
    print(f'{a} is not None')
else:
    print(f'{a} is None')
# 0 is None

ここでもx is not Noneを使うべきである。

a = None

if a is not None:
    print(f'{a} is not None')
else:
    print(f'{a} is None')
# None is None

a = 0

if a is not None:
    print(f'{a} is not None')
else:
    print(f'{a} is None')
# 0 is not None

関連カテゴリー

関連記事