Pythonのnullオブジェクト?


1193

Pythonでnullオブジェクトを参照するにはどうすればよいですか?

回答:


1629

Pythonでは、「null」オブジェクトはシングルトンNoneです。

「Noneness」を確認する最良の方法は、アイデンティティ演算子を使用することですis

if foo is None:
    ...

125
そして、egg is Noneover を選択する理由egg == None:後者はオーバーロードされる可能性があり、有効なオブジェクトをNoneと比較すると壊れる可能性があります(実装方法によって異なりますが、誰もがNoneとの比較を考慮に入れることを期待していませんか?) 、is常に同じように動作します。

94
Pythonデザイナーが「null」を選択しなかったのはなぜですか。違いはありませんか?;)
Vidar 2013年

35
@Vidar 'None'はオブジェクトの欠如ではなく( 'null'はnull参照である)、実際のオブジェクトです。「NoneType」以外のタイプのオブジェクトに「None」オブジェクトが渡されることはありません。また、言語の概念でもありません。Pythonに組み込まれているわけではなく、Pythonの標準ライブラリの一部です。なし!==(
ahem

11
@ naught101それは何の役にも立たないでしょう。ポインタの概念がないので。ctypesライブラリを使用している場合、Noneはアドレス0の同義語として使用されますが、「null参照」という言語の概念はまだありません。Pythonでは、そのオブジェクトがNoneであっても、常にある種のオブジェクトを参照したままにします。これは言語を大幅に簡略化すると思います。
Rushyo 14

5
null参照である「10億ドルの間違い」を説明するすばらしいプレゼンテーション:infoq.com/presentations/…。null以外の他のオプションは、オプションまたは多分(カスタム)タイプです。
Michael Trouw 2015

134

None、Pythonのnull?

nullPythonにはありませんが、代わりにがありNoneます。すでに述べたように、何かがNone値として与えられていることをテストする最も正確な方法はis、2つの変数が同じオブジェクトを参照していることをテストする恒等演算子を使用することです。

>>> foo is None
True
>>> foo = 'bar' 
>>> foo is None
False

基礎

1つしかありません 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

NonePythonの識別関数を使用して、一意性を確認できます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

その意味を理解し、なぜ明示的にするのが良いアイデアであることがよくあるかを理解する必要があります。

ケース1:値があるかどうかのテスト 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

ケース2: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ます。ただし、これはに固有のプロパティではないことに注意してくださいNoneFalseそれ自体に加えて、プロパティは、空のリスト、タプル、セット、ディクショナリ、文字列、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 シグナル値として使用

NonePythonでは特別なステータスがあります。多くのアルゴリズムがそれを例外的な値として扱うため、これはお気に入りのベースライン値です。このようなシナリオでは、これをフラグとして使用して、条件に特別な処理(デフォルト値の設定など)が必要であることを通知できます。

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 フラグと有効な値の両方として使用されます

上記のNoneapplyの使用法は、有効な値とは見なされないが、何か特別なことをするための信号のようなものです。ただし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で番兵を作成するのは簡単です。NoneNoneNone

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を拡張または補足することが目的である場合にのみ、それを認識する必要があります。


何について:なし==事?
hkBst

@hkBstあなたの質問はpythonが同等性を評価する方法についてだと思います。このstackoverflow.com/questions/3588776/…をご覧ください
Michael Ekoka

ああ、そういうわけで通常IIUCはまだ物事を呼び出すことになります。__eq__?その場合、私の提案を撤回します。
hkBst 2018年

@MichaelEkokaは、この印象的で有用な情報のソースを共有できますか。
Anidhya Bhatnagar 2018

標準的な練習。Pythonチュートリアルを実行することでいくつかのヒントを見つけることができますが、人気のあるプロジェクトのソースコードを読むことが、慣用的なPythonにすばやく没頭するための一番のアドバイスです
Michael Ekoka

67

これは、他の言語でnullとして呼び出されますが、ないですNone。このオブジェクトのインスタンスは常に1つしかないため、必要に応じて、x is Noneではなく(同一性比較)との同等性を確認できx == Noneます。


25
私はを再インスタンス化してPythonを壊す方法を見つけようとしていますNone。次に、比較するすべての賢い人々NoneTypeが勝利します!
Zenexer 2013

28

Pythonでは、値の不在を表すために、オブジェクトにはNone値(types.NoneType.None)を、文字列には""(またはlen()== 0)を使用できます。したがって:

if yourObject is None:  # if yourObject == None:
    ...

if yourString == "":  # if yourString.len() == 0:
    ...

「==」と「is」の違いについては、「==」を使用してオブジェクトの同一性をテストすることで十分です。ただし、操作「is」はオブジェクトID操作として定義されているため、「==」ではなく、操作を使用する方が適切です。速度の違いさえあるかどうかわからない。

とにかく、あなたは見ることができます:


8
私の知る限り、(0 == false)はすべてのプログラミング言語でtrueを返します。これは、falseは0としてコード化され、「true」は0以外のすべてのものとしてコード化されるためです。ただし、「is」演算子は「==」演算子と同じではないことに注意してください。これは、Javaの「==」と「equals」の違いはほぼ同じです。実際、演算子「is」は、2つのオブジェクトが同じ(同じインスタンスであり、同じコンテンツではない)かどうかをチェックします。
Paolo Rovelli

12
Paolo、FYI、(0 == false)は、すべてのプログラミング言語でtrueを返すわけではありません。(0 == false)がfalseを返すScalaは簡単なカウンターの例です。数値をブール値と比較するときにfalseを返すプログラミング言語はScalaだけではないと私は確信しています。
Rob Wilton、2014

2
はい、わかった!次に、ほとんどのプログラミング言語について考えてみましょう。
Paolo Rovelli 2014

3
JavaScriptで0 == false返さtrueれる理由は、二重等号演算子が型強制を行うためです。ただし、3つの等号演算子では、「数値」と「ブール値」は異なる型であるため、を0 === false返しますfalse
jkdev '18年

1
@ PaoloRovelli、Lua、Ruby、およびClojureでは、0はtrue条件文と同様に扱われます。Rust and Goでは0false 同等であるかどうかを比較できないさまざまなタイプです。
スクーターダングル2017

0

Nullは次のような特別なオブジェクトタイプです。

>>>type(None)
<class 'NoneType'>

オブジェクトがクラス「NoneType」にあるかどうかを確認できます。

>>>variable = None
>>>variable is None
True

詳細については、Pythonドキュメントをご覧ください。


-1

真理値ごとのテストでは、「なし」は直接FALSEとしてテストされるため、最も単純な式で十分です。

if not foo:

3
いいえ、ありません。その式は、だけでなく、偽の値Trueに対して戻りますNone
insert_name_here 2017

確かに、そして単純な「if not foo:」は、述べたように、元の質問に正しく答えません。ただし、Pythonは動的に型指定されており、構文プロトコルを削減するように求められているため、より単純で類似した構成を検討することは私には有効であると思われます。
artejera 2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.