null判定とNoneとNoneType

今回のテーマは値がNoneかどうかの判定方法について。
javaなどでいういわゆるnull判定。

None

Noneについては

  • 3. データモデル — Python 2.7.x ドキュメント

    この型には単一の値しかありません。この値を持つオブジェクトはただ一つしか存在しません。このオブジェクトは組み込み名 None でアクセスされます。このオブジェクトは、様々な状況で値が存在しないことをしめします。例えば、明示的に値を返さない関数は None を返します。 None の真値 (truth value) は偽 (false) です。

Noneは条件式ではFalseと判定される事になる。

if None:
    print "True"
else:
    print "False"

実行結果

False

その他の型の真偽判定については

Noneの判定方法にはいろいろとあって

==演算子やis演算子を使って判定できる。

x = None
print x == None, x is None
True True

否定は

print x != None, x is not None

実行結果

False False

==演算子is演算子の違いは、is演算子と==演算子と特殊メソッド__eq__で述べたとおり==演算子が同じ値かどうかを判定するのに対して、is演算子は同じインスタンスかどうかを判定する

他のサイトの記事を参考すると、Noneの判定には==演算子よりis演算子を使った方がいいらしい。

is演算子の方がスピードが速いらしい。
また、==演算子の場合には、is演算子と==演算子と特殊メソッド__eq__で述べたとおり==演算子は特殊メソッド__eq__に変換されるので、レアケースであるが以下のようなヘンテコなクラスが実装されていた場合には値がNoneでなくともTrueと判定されてしまう。

class MyCls(object):
    def __eq__(self,other):
        return other is None

x=MyCls()
print x==None, x is None

実行結果

True False

NoneType

Noneの型はNoneType。
NoneはNoneTypeクラスのインタンスとして定義されている。
NoneTypeというキーワードは、変数がNone以外の値を期待するありがちなバグによるエラーメッセージでよく見かけることがある。
次のコードは、その例である。

def get_sql_string(table_name):
    if type(table_name) == str and table_name != "":
        return str.format("  select * from {0}  ", table_name)
    else:
        return None

s = get_sql_string("")
print s.strip()

上記のコードは、getSqlString関数を定義してテーブル名を引数に渡してSQLのselect文を生成しているが、テーブル名が文字列型で無い場合や空文字の場合にNoneを返す。
テーブル名が文字列型で無い場合や空文字の場合には、関数の戻り値がNoneになってしまうのでその後の処理でstripメソッドを使って前後の空白文字を取り除こうとするとエラーが発生してしまう。

実行結果

AttributeError: 'NoneType' object has no attribute 'strip'

None型にはstripメソッドなんて無いですよという事になる。

冒頭の公式ドキュメントの引用のように「この型には単一の値しかありません。」なので、NoneTypeはsingletonでありNoneはNoneType型の唯一のインスタンスという事になる。
従って、NoneTypeを使って値がNoneかどうかの判定方法が可能という事になる。(パフォーマンスの問題はさておいて)

やる事は無いと思うけど、NoneTypeは継承できないみたい。

NoneTypeを使って実際にNoneの判定をおこなってみる。

x=None

import types
print type(x) == types.NoneType

NoneTypeはコードの中に直接記述する事はできない。
かわりに、上記のコードのようにtypesモジュールのNoneTypeを使う。

実行結果

True

同様に、is演算子や組込み関数isinstanceを使ってNoneの判定をおこなう事も可能である。

type(x) is types.NoneType

isinstance(x, types.NoneType)

type関数やisinstance関数については

ページのトップへ戻る