PythonではnullはNoneだった
- 作成日: 2021-07-07
- 更新日: 2023-12-24
- カテゴリ: Python
PythonではnullはNoneだった
Pythonではnull
に相当するとオブジェクトはNoneになります。
None
はオブジェクトの未定義の状態や、何もない状態を表現します。
結論から言うとPythonのNone
は↓のように使います。
var = None # 変数の中身をNoneにする
print(var)
# None
def func(): # 返り値を持たない関数を定義する
pass
result = func() # 返り値はNone
print(result)
# None
この記事ではNone
の特性や扱い方について解説します。
具体的には↓を見ていきます。
null
とは?None
とは?None
の正体None
の使い方None
にいたずらする
nullとは?Noneとは?
null(ナル)とは何も存在しないことを表すオブジェクトです。
この変数の値はnull
だ、とか、この関数の返り値はnull
だ、と言う風に使います。
プログラムでは「何もない」とか「存在しない」という表現にnull
が慣例的に良く使われます。
たとえばC言語ではNULL
というオブジェクトが存在し、これが代入されているポインタはナルポインタと呼ばれ、何も存在しないポインタという意味で使われます。
何も存在しないので、ナルポインタにアクセスするとセグフォが起きたりしてプログラムが止まったりします。
NULL
の実体はただの0
という整数を(void *)
型にキャストしただけのもであることが多いです。
またSQL
ではNULL
というキーワードを使ってフィールドに空の状態を設定できます。
NULL
が設定されたフィールドの値は空になります。
プログラムでは明示的に「何も存在しない」という定義が必要です。
なぜならそのほうがプログラムの開発がしやすくなるからです。
「何も存在しない」という定義が存在しなければ、変数は「何も存在しない」状態を表現できなくなるため、常に何かの値が代入されている必要があります。
しかしnull
があれば、明示的に「何も存在しない」という状態を表現できるため、変数に代入しておくことが出来ます。
このようにプログラミングで使われるnull
はプログラムの便宜性のために生まれました。
Pythonでもこの定義があり、null
に相当するものはNone
になります。
言語設計者が設計にnull
を組み込んでいるわけです。
Noneの正体
None
は組み込み定数と呼ばれ、どこからでも参照することが出来ます。
None
の正体はtype()
で確認できます。
print(type(None))
# <class 'NoneType'>
NoneType
というのがNone
の型です。
このNoneType
が生成した唯一のオブジェクトがNone
オブジェクトです。
変数にNone
を代入し、それのid()
を確認すると、None
が一意のオブジェクトであることがわかります。
a = None
b = None
print(id(a))
# 9621664
print(id(b))
# 9621664
↑の場合、変数a
とb
のid()
の結果が両方とも同じ値になっています。
これは変数a
とb
に代入されているオブジェクトが共にNone
だからです。
id()
はオブジェクトのアイデンティティを返します。アイデンティティとはオブジェクトのユニーク性を表す整数です。
つまりアイデンティティが同じであればそのオブジェクトは同じオブジェクトであると言えます。
↑の場合は変数a
とb
のアイデンティティは同じなので、2つは同じオブジェクト(None
)ということになります。
Noneの使い方
None
の基本的な使い方です。
変数への代入
None
は変数に代入することが出来ます。
var = None
print(var)
# None
もちろん変数から変数の代入も可能です。その場合、値は同じNone
オブジェクトになります。
a = None
b = a
print(a, b)
# None None
引数のデフォルト値
関数の引数のデフォルト値にもNone
はよく使われます。
def func(a=None):
print(a)
# None
func()
関数の返り値
また、return
が書かれていない関数はデフォルトでNone
を返します。
def func():
pass
result = func()
print(result)
# None
return
が書かれていて、値が省略されている場合もNone
を返します。
def func():
return
result = func()
print(result)
# None
Noneの比較
None
の比較には==
やis
が使えます。
if None == None:
print('== none')
# == none
a = None
if a == None:
print('== none')
# == none
if None is None:
print('is none')
# is none
a = None
if a is None:
print('is none')
# is none
比較には==
とis
のどちらも使えますが、None
がユニークなオブジェクトであることを考えるとより厳密に比較したい場合はis
を使ったほうが良いでしょう。
is
はオブジェクトのアイデンティティを比較します。
そのためユニークなNone
と比較すれば絶対的にNone
かどうか比較できます。
==
は__eq__()
を定義すればその振る舞いを変更できてしまうため、厳密性に欠けると言えます。
class Animal:
def __eq__(self, other):
return True
a = Animal()
print(a == None)
# True
↑の場合、変数a
はNone
ではありませんが、__eq__()
で==
の振る舞いを変更しているため結果がTrue
になっています。
リストの中のNone
リストにNone
を保存した場合、その長さはしっかり増えます。
「存在しない」が2つになるわけです。なんだか不思議ですね。
lis = [None, None]
print(len(lis))
# 2
Noneにいたずらする
None
にいたずらはできるのでしょうか?
値を上書きしたりとか?
結論から言うとできません。
None
はPythonから保護されています。
None += 1
# SyntaxError: 'None' is an illegal expression for augmented assignment
↑のようにNone
に1
を加算代入しようとするとPythonから怒られます。
翻訳すると「None
は拡張代入では不正な式です」になります。
🦝 < 加算代入できねーぞ、ってことね
おわりに
今回はPythonのnull
とNone
について見てみました。
Pythonではnull
に相当するものはNone
です。
🦝 < 私の人生は`None`
🐭 < お財布の中身は`None`