回答:
Pythonでは、「null」オブジェクトはシングルトンNone
です。
「Noneness」を確認する最良の方法は、アイデンティティ演算子を使用することですis
。
if foo is None:
...
None
、Pythonのnull?null
Pythonにはありませんが、代わりにがありNone
ます。すでに述べたように、何かがNone
値として与えられていることをテストする最も正確な方法はis
、2つの変数が同じオブジェクトを参照していることをテストする恒等演算子を使用することです。
>>> foo is None
True
>>> foo = 'bar'
>>> foo is None
False
None
None
はクラスの唯一のインスタンスであり、そのクラスNoneType
をインスタンス化しようとすると、同じオブジェクトが返され、None
シングルトンになります。PythonのNoneType
初心者は、それが何であるかを言及し、疑問に思うエラーメッセージをよく目にします。None
後で説明するように、None
あいまいさの余地がほとんどないため、これらのメッセージは単に名前で単に言及できるというのは私の個人的な意見です。したがって、これを実行できない、または実行できないことTypeError
を言及するメッセージが表示された場合はNoneType
、それが単に、None
それができない方法で使用されていたものであることを知ってください。
また、None
組み込み定数です。Pythonを起動するとすぐに、モジュール、クラス、関数など、どこからでも使用できます。NoneType
対照的に、そうではありませんNone
。まず、そのクラスを照会することにより、その参照を取得する必要があります。
>>> NoneType
NameError: name 'NoneType' is not defined
>>> type(None)
NoneType
None
Pythonの識別関数を使用して、一意性を確認できますid()
。オブジェクトに割り当てられた一意の番号を返します。各オブジェクトには1つあります。2つの変数のIDが同じ場合、それらは実際には同じオブジェクトを指します。
>>> NoneType = type(None)
>>> id(None)
10748000
>>> my_none = NoneType()
>>> id(my_none)
10748000
>>> another_none = NoneType()
>>> id(another_none)
10748000
>>> def function_that_does_nothing(): pass
>>> return_value = function_that_does_nothing()
>>> id(return_value)
10748000
None
上書きできませんPythonのかなり古いバージョン(2.4より前)ではNone
、を再割り当てすることはできましたが、それ以上はできません。クラス属性としても、関数の範囲内にもありません。
# In Python 2.7
>>> class SomeClass(object):
... def my_fnc(self):
... self.None = 'foo'
SyntaxError: cannot assign to None
>>> def my_fnc():
None = 'foo'
SyntaxError: cannot assign to None
# In Python 3.5
>>> class SomeClass:
... def my_fnc(self):
... self.None = 'foo'
SyntaxError: invalid syntax
>>> def my_fnc():
None = 'foo'
SyntaxError: cannot assign to keyword
したがって、すべてのNone
参照が同じであると想定しても安全です。「カスタム」はありませんNone
。
None
使用をテストするにはis
コードを書くとき、次のようにNonenessをテストしたくなるかもしれません:
if value==None:
pass
または、このような偽りをテストするには
if not value:
pass
その意味を理解し、なぜ明示的にするのが良いアイデアであることがよくあるかを理解する必要があります。
None
なぜこれをするのですか
value is None
のではなく
value==None
最初のものは次と同等です:
id(value)==id(None)
表現value==None
は実際にはこのように適用されますが
value.__eq__(None)
値が実際の場合、None
期待どおりの結果が得られます。
>>> nothing = function_that_does_nothing()
>>> nothing.__eq__(None)
True
ほとんどの一般的なケースでは結果は同じですが、__eq__()
メソッドは正確な保証を無効にするドアを開きます。これは、クラスでオーバーライドされて特別な動作を提供できるためです。
このクラスを考えてみましょう。
>>> class Empty(object):
... def __eq__(self, other):
... return not other
だから、上でそれを試しNone
、それが動作します
>>> empty = Empty()
>>> empty==None
True
しかし、それは空の文字列でも機能します
>>> empty==''
True
それでも
>>> ''==None
False
>>> empty is None
False
None
ブール値として使用する次の2つのテスト
if value:
# do something
if not value:
# do something
実際に次のように評価されます
if bool(value):
# do something
if not bool(value):
# do something
None
は「false」です。つまり、ブール値にキャストすると返さFalse
れ、not
演算子を適用するとが返されTrue
ます。ただし、これはに固有のプロパティではないことに注意してくださいNone
。False
それ自体に加えて、プロパティは、空のリスト、タプル、セット、ディクショナリ、文字列、0、および__bool__()
マジックメソッドを実装するクラスからのすべてのオブジェクトによって返されFalse
ます。
>>> bool(None)
False
>>> not None
True
>>> bool([])
False
>>> not []
True
>>> class MyFalsey(object):
... def __bool__(self):
... return False
>>> f = MyFalsey()
>>> bool(f)
False
>>> not f
True
したがって、次の方法で変数をテストするときは、テストに含めるものまたはテストから除外するものに特に注意してください。
def some_function(value=None):
if not value:
value = init_value()
上記でinit_value()
、値がに特別に設定されたときに呼び出すNone
ことを意味しました0
か、またはに設定された値、空の文字列、または空のリストも初期化をトリガーする必要があることを意味しましたか?私が言ったように、注意してください。多くの場合、Pythonの場合は、暗黙よりも明示的な方が優れています。
None
実際にはNone
シグナル値として使用None
Pythonでは特別なステータスがあります。多くのアルゴリズムがそれを例外的な値として扱うため、これはお気に入りのベースライン値です。このようなシナリオでは、これをフラグとして使用して、条件に特別な処理(デフォルト値の設定など)が必要であることを通知できます。
None
関数のキーワード引数に割り当てて、明示的にテストすることができます。
def my_function(value, param=None):
if param is None:
# do something outrageous!
オブジェクトの属性にアクセスしようとしたときにデフォルトとしてそれを返し、特別なことをする前に明示的にテストすることができます。
value = getattr(some_obj, 'some_attribute', None)
if value is None:
# do something spectacular!
デフォルトでは、存在しないキーにアクセスしようとすると、ディクショナリのget()
メソッドが返さNone
れます。
>>> some_dict = {}
>>> value = some_dict.get('foo')
>>> value is None
True
表記あなたは添字を使用してアクセスしようとした場合KeyError
提起されるだろう
>>> value = some_dict['foo']
KeyError: 'foo'
同様に、存在しないアイテムをポップしようとした場合
>>> value = some_dict.pop('foo')
KeyError: 'foo'
通常は次のように設定されているデフォルト値で抑制できます。 None
value = some_dict.pop('foo', None)
if value is None:
# booom!
None
フラグと有効な値の両方として使用されます上記のNone
applyの使用法は、有効な値とは見なされないが、何か特別なことをするための信号のようなものです。ただしNone
、信号として使用されていてもデータの一部である可能性があるため、どこから来たのかを知ることが重要な場合があります。
getattr(some_obj, 'attribute_name', None)
戻っNone
てオブジェクトの属性を照会しても、アクセスしようとしていた属性が設定されているNone
かどうか、またはオブジェクトにまったく存在しないかどうかはわかりません。のようなディクショナリからキーにアクセスするときと同じ状況で、欠落しているかどうか、または単にに設定されているかどうsome_dict.get('some_key')
かsome_dict['some_key']
はわかりませんNone
。その情報が必要な場合、これを処理する通常の方法は、try/except
構成内から属性またはキーに直接アクセスすることです。
try:
# equivalent to getattr() without specifying a default
# value = getattr(some_obj, 'some_attribute')
value = some_obj.some_attribute
# now you handle `None` the data here
if value is None:
# do something here because the attribute was set to None
except AttributeError:
# we're now hanling the exceptional situation from here.
# We could assign None as a default value if required.
value = None
# In addition, since we now know that some_obj doesn't have the
# attribute 'some_attribute' we could do something about that.
log_something(some_obj)
同様にdictで:
try:
value = some_dict['some_key']
if value is None:
# do something here because 'some_key' is set to None
except KeyError:
# set a default
value = None
# and do something because 'some_key' was missing
# from the dict.
log_something(some_dict)
上記の2つの例は、オブジェクトとディクショナリのケースを処理する方法を示していますが、関数についてはどうですか?同じことですが、そのために二重のアスタリスクキーワード引数を使用しています。
def my_function(**kwargs):
try:
value = kwargs['some_key']
if value is None:
# do something because 'some_key' is explicitly
# set to None
except KeyError:
# we assign the default
value = None
# and since it's not coming from the caller.
log_something('did not receive "some_key"')
None
有効な値としてのみ使用されますフラグとデータをtry/except
単に区別するために、コードに上記のパターンが散らかっている場合は、別のテスト値を使用してください。有効な値のセットの外にある値がデータ構造のデータの一部として挿入され、特別な条件(境界、状態など)を制御およびテストするために使用されるパターンがあります。このような値はセンチネルと呼ばれ、信号として使用される方法で使用できます。Pythonで番兵を作成するのは簡単です。None
None
None
undefined = object()
上記のundefined
オブジェクトは一意であり、プログラムにとって重要なことは何もしないためNone
、フラグとしての優れた代替品です。いくつかの注意事項が適用されます。詳細はコードの後で説明します。
機能付き
def my_function(value, param1=undefined, param2=undefined):
if param1 is undefined:
# we know nothing was passed to it, not even None
log_something('param1 was missing')
param1 = None
if param2 is undefined:
# we got nothing here either
log_something('param2 was missing')
param2 = None
辞書付き
value = some_dict.get('some_key', undefined)
if value is None:
log_something("'some_key' was set to None")
if value is undefined:
# we know that the dict didn't have 'some_key'
log_something("'some_key' was not set at all")
value = None
オブジェクト付き
value = getattr(obj, 'some_attribute', undefined)
if value is None:
log_something("'obj.some_attribute' was set to None")
if value is undefined:
# we know that there's no obj.some_attribute
log_something("no 'some_attribute' set on obj")
value = None
先に述べたように、カスタムセンチネルには注意事項がいくつかあります。まず、これらはのようなキーワードでNone
はないため、Pythonでは保護されません。undefined
上記は、定義されているモジュール内の任意の場所でいつでも上書きできるため、それらを公開して使用する方法に注意してください。次に、によって返されるインスタンスはobject()
シングルトンではありません。その呼び出しを10回行うと、10の異なるオブジェクトが取得されます。最後に、番兵の使い方は非常に特異的です。番兵はそれが使用されているライブラリに固有であり、そのため、その範囲は通常、ライブラリの内部に限定されます。「漏れる」ことはありません。外部コードは、ライブラリのAPIを拡張または補足することが目的である場合にのみ、それを認識する必要があります。
これは、他の言語でnullとして呼び出されますが、ないですNone
。このオブジェクトのインスタンスは常に1つしかないため、必要に応じて、x is None
ではなく(同一性比較)との同等性を確認できx == None
ます。
None
。次に、比較するすべての賢い人々NoneType
が勝利します!
Pythonでは、値の不在を表すために、オブジェクトにはNone値(types.NoneType.None)を、文字列には""(またはlen()== 0)を使用できます。したがって:
if yourObject is None: # if yourObject == None:
...
if yourString == "": # if yourString.len() == 0:
...
「==」と「is」の違いについては、「==」を使用してオブジェクトの同一性をテストすることで十分です。ただし、操作「is」はオブジェクトID操作として定義されているため、「==」ではなく、操作を使用する方が適切です。速度の違いさえあるかどうかわからない。
とにかく、あなたは見ることができます:
0 == false
返さtrue
れる理由は、二重等号演算子が型強制を行うためです。ただし、3つの等号演算子では、「数値」と「ブール値」は異なる型であるため、を0 === false
返しますfalse
。
true
条件文と同様に扱われます。Rust and Goでは0
、false
同等であるかどうかを比較できないさまざまなタイプです。
Nullは次のような特別なオブジェクトタイプです。
>>>type(None)
<class 'NoneType'>
オブジェクトがクラス「NoneType」にあるかどうかを確認できます。
>>>variable = None
>>>variable is None
True
詳細については、Pythonドキュメントをご覧ください。
True
に対しても戻りますNone
。
egg is None
over を選択する理由egg == None
:後者はオーバーロードされる可能性があり、有効なオブジェクトをNoneと比較すると壊れる可能性があります(実装方法によって異なりますが、誰もがNoneとの比較を考慮に入れることを期待していませんか?) 、is
常に同じように動作します。