回答:
ステートメント
if A:
呼び出しA.__nonzero__()(特別なメソッド名のドキュメントを参照)、その関数の戻り値を使用します。要約は次のとおりです。
object.__nonzero__(self)真理値テストと組み込み操作を実装するために呼び出され
bool()ます。返すべきであるFalseかTrue、またはその整数同等0か1。このメソッドが定義されていない__len__()場合、が定義されていれば呼び出され、その結果がゼロ以外であればオブジェクトは真と見なされます。クラスがもも定義してい__len__()ない場合、__nonzero__()そのすべてのインスタンスはtrueと見なされます。
一方、
if A is not None:
参照のみを比較AしNoneて、同じかどうかを確認します。
if object(): passループあたりif object() is not None: pass〜0.130 usecですが、〜0.135 usecです。いずれにせよ、これら2つを選択するためにパフォーマンスを使用するのではなく、同等ではないため、動作の違いを確認してください。
if A is not Noneは、比較のために組み込みのシングルトンNoneを比較するための中間ステップとしてロードする必要があるため、遅くなるようですA(を参照してくださいdis.dis())。私が間違っているがif A:、Noneアイデンティティではなく真の値を実際にテストしたい場合は、より効率的であると思われる場合に修正してください。
python -m timeit -s"a=0" "if a: pass" "else: pass"より高速ですpython -m timeit -s"a=0" "if a is None: pass" "else: pass"がpython -m timeit -s"a=1" "if a: pass" "else: pass"低速です。プラットフォームに依存する可能性があります。同じ結果が得られるかどうかを確認してください
is Noneテストは確かに私にとって最も低速でした。pypyでは、それらはすべてまったく同じように測定されました:)
に書かれているように PEP8でように:
のようなシングルトンとの比較 None は、常に 'is'または 'is not'を使用して行う必要があります。等価演算子は使用しないでください。
また、「もしxがNoneでない」ことを本当に意味している場合、 たとえば、デフォルトでNoneになっている変数または引数が他の値に設定されているかどうかをテストする場合は、「if x」を書くことに注意してください。他の値には、ブール値のコンテキストではfalseになる可能性のあるタイプ(コンテナーなど)がある場合があります。
None、真理値のチェックに関心があります。この場合、if A:より効率的に見えます(aをdis.dis()実行すると、組み込みをロードしてNoneと比較する追加の手順がありますが、他の場合if A is not None:にはaしかありませんjump_if)。
適切な結果がない場合、多くの関数はNoneを返します。たとえば.first()、結果に行がなかった場合、SQLAlchemyクエリのメソッドはNoneを返します。0を返す可能性のある値を選択していて、その値が実際に0かどうか、またはクエリにまったく結果がないかどうかを知る必要があるとします。
一般的なイディオムは、関数またはメソッドのオプションの引数にデフォルト値のNoneを指定し、その値がNoneであることをテストして、指定されているかどうかを確認することです。例えば:
def spam(eggs=None):
if eggs is None:
eggs = retrievefromconfigfile()
それと比較してください:
def spam(eggs=None):
if not eggs:
eggs = retrievefromconfigfile()
後者の場合、spam(0)またはを呼び出すとどうなりますかspam([])?関数は(誤って)値を渡していないことを検出しますeggs、デフォルト値を計算します。それはおそらくあなたが望むものではありません。
または、「特定のアカウントのトランザクションのリストを返す」のような方法を想像してみてください。アカウントが存在しない場合、Noneが返される可能性があります。これは、空のリストを返すこととは異なります(つまり、「このアカウントは存在しますが、トランザクションは記録されていません)。
最後に、データベースに戻ります。NULLと空の文字列の間には大きな違いがあります。空の文字列は通常、「ここに値があり、その値はまったく何もない」と言います。NULLは、「この値は入力されていません」と言います。
これらのいずれの場合も、を使用する必要がありますif A is None。特定の値をチェックしている-なし-「たまたまFalseにキャストされる値」だけではない。
彼らは非常に異なることをします。
以下のチェックAが値以外のものを持っている場合はFalse、[]、None、''と0。A の値をチェックします。
if A:
以下は、AがNoneと異なるオブジェクトかどうかをチェックします。AとNone の参照(メモリアドレス)をチェックして比較します。
if A is not None:
更新:詳細説明
多くの場合、2つは同じことをするように見えるので、多くの人がそれらを交換可能に使用します。これは本当に悪い考えです。2つが同じ結果をもたらす理由は、インターニングのようなインタープリター/コンパイラーの最適化による純粋な偶然によるものです。や他の何かのものです。
これらの最適化を念頭に置いて、同じ値の整数と文字列は、同じメモリ空間を使用することになります。これはおそらく、2つの別々の文字列が同じであるかのように動作する理由を説明しています。
> a = 'test'
> b = 'test'
> a is b
True
> a == b
True
他のことは同じように動作しません。
> a = []
> b = []
> a is b
False
> a == b
True
2つのリストには明らかに独自の記憶があります。驚くべきことに、タプルは文字列のように動作します。
> a = ()
> b = ()
> a is b
True
> a == b
True
これはタプルが変更されないことが保証されているためと考えられ、同じメモリを再利用することには意味があります。
これの結論は偶然に頼ることができないということです。アヒルのように鳴くからといって、それがアヒルであるとは限りません。使用isして==、あなたが本当にチェックしたいものに応じて。これらのことはis、私たちがよくそれを読み飛ばす散文のように読まれるので、デバッグが難しい場合があります。
Noneシングルトンであり、これは実装の詳細ではありません(intやstring interningとは異なります)。私があなたの言っていることを理解しているとは思いません。
Noneは異なる、intまたはstrインターンが原因の動作ではありません。私のポイントはそれでisあり==、さまざまなことをチェックしています。最初はメモリアドレスをチェックし、2番目はメモリアドレスの内容をチェックします。
どれもPythonでは特別な値であり、通常は初期化されていない変数を指定します。Aにこの特定の値がないかどうかをテストするには、次を使用します。
if A is not None
Falsey値はPythonのオブジェクトの特別なクラスです(例:false、[])。Aが誤っているかどうかをテストするには:
if not A
したがって、2つの式は同じではなく、それらを同義語として扱わない方がよいでしょう。
PS Noneも誤っているため、最初の式は2番目の式を意味します。しかし、2つ目は、None以外の誤った値をカバーしています。ここで... AのNone以外に他の偽の値を使用できないことが確実な場合は、最初の式を2番目の式に置き換えることができます。
状況によります。
ある種のコレクションになることをif A:期待しAているときに使用します。コレクションが空でない場合にのみブロックを実行します。これにより、呼び出し側は、空であるかどうかにかかわらず、適切に動作するコレクションを渡し、期待どおりの動作をさせることができます。また、ブロックの実行を許可NoneおよびFalse抑制します。これは、コードを呼び出すのに便利な場合があります。
OTOH、私は期待している場合A、いくつかの完全に任意のオブジェクトであることを、それはにデフォルト設定されている可能性がNone、私は、いつも使うif A is not None呼び出すコードが故意に空のコレクション、空の文字列、または0の値を持つ数値型への参照を渡すことができたとして、またはboolean False、またはブールコンテキストでたまたまfalseとなるクラスインスタンス。
そして、その一方で、Aより具体的なもの(たとえば、メソッドを呼び出すクラスのインスタンス)を期待している場合は、デフォルトでになっている可能性がありNone、デフォルトのブール変換はすべてのサブクラスに強制することを気にしないクラスのプロパティです。次にif A:、追加の12文字を入力する手間の負担を軽減するために使用します。
というファイルを作成test.pyし、インタプリタで実行しました。目的を変更して、舞台裏での状況をテストすることができます。
import dis
def func1():
matchesIterator = None
if matchesIterator:
print( "On if." );
def func2():
matchesIterator = None
if matchesIterator is not None:
print( "On if." );
print( "\nFunction 1" );
dis.dis(func1)
print( "\nFunction 2" );
dis.dis(func2)
これがアセンブラの違いです。

ソース:
>>> import importlib
>>> reload( test )
Function 1
6 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
8 6 LOAD_FAST 0 (matchesIterator)
9 POP_JUMP_IF_FALSE 20
10 12 LOAD_CONST 1 ('On if.')
15 PRINT_ITEM
16 PRINT_NEWLINE
17 JUMP_FORWARD 0 (to 20)
>> 20 LOAD_CONST 0 (None)
23 RETURN_VALUE
Function 2
14 0 LOAD_CONST 0 (None)
3 STORE_FAST 0 (matchesIterator)
16 6 LOAD_FAST 0 (matchesIterator)
9 LOAD_CONST 0 (None)
12 COMPARE_OP 9 (is not)
15 POP_JUMP_IF_FALSE 26
18 18 LOAD_CONST 1 ('On if.')
21 PRINT_ITEM
22 PRINT_NEWLINE
23 JUMP_FORWARD 0 (to 26)
>> 26 LOAD_CONST 0 (None)
29 RETURN_VALUE
<module 'test' from 'test.py'>
前者はよりPythonic(より良い表意コード)ですが、AがFalse(Noneではない)の場合はブロックを実行しません。
is/is not None。次のPEP8はPythonicです。さらに、2つのテストは異なります。
python> = 2.6、
次のように書けば
if A:
警告を生成します、
FutureWarning:このメソッドの動作は将来のバージョンで変更されます。代わりに、特定の 'len(elem)'または 'elem is not None'テストを使用してください。
だから私たちは使うことができます
if A is not None:
A is not None行う必要のある作業がはるかに少ないので、高速になります