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演算子を使った方がいいらしい。
- PythonではNoneの比較は==ではなくisを使う - こんにちはこんにちはmonmonです!
「==は__eq__が呼び出されるからTrue返すように定義するとNoneじゃないのにTrueにできちゃうよ。それにisでNoneを判別した方が==で判別するより相当速いよ」 みたいな事が書いてありました。
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関数については