2013-08-16 14 views
6

is演算子がid()比較を行っていると思っていた(誤っているかもしれません)。Pythonで 'is'演算子は何をしますか?

>>> x = 10 
>>> y = 10 
>>> id(x) 
1815480092 
>>> id(y) 
1815480092 
>>> x is y 
True 

しかし、val is not Noneでは、そう簡単ではないようです。

>>> id(not None) 
2001680 
>>> id(None) 
2053536 
>>> val = 10 
>>> id(val) 
1815480092 
>>> val is not None 
True 

次に、 'is'演算子は何ですか?ちょうど私が推測したオブジェクトIDの比較ですか?その場合、val is not NoneはPythonでnot (val is None)と解釈されますか?

+0

はい、「valはNoneではありません」、「not(valはNone)」は[同等]です(http://stackoverflow.com/questions/12941287/does-not-e-in-c-differ-from -e-in-c-in-python)を使用します。しかし、最初のものはより読みやすいIMOです。 –

答えて

10

あなたは、is notがオペレータであることを逃しましたtooです。 isなし

、正規notオペレータは、ブール値を返す:

>>> not None 
True 

not NoneしたがってNoneの逆ブール '値' です。ブール値のコンテキストNoneではfalseです。

>>> bool(None) 
False 

のでnot NoneがブールTrueです。

NoneTrue両方があまりにもオブジェクトであり、両方のメモリアドレス(パイソンのCPythonの実装の値id()リターン)を有する:

>>> id(True) 
4440103488 
>>> id(not None) 
4440103488 
>>> id(None) 
4440184448 

isテスト2つの参照は、同じオブジェクトを指している場合;何かが同じオブジェクトならば、それは同じid()も持っています。 isは、ブール値TrueまたはFalseを返します。

is notは、is演算子の逆です。これは、1つの演算子でnot (op1 is op2)に相当します。それはがここにop1 is (not op2)として読まれるべきではない:マルタインピータース答えを補完するものとして

>>> 1 is not None  # is 1 a different object from None? 
True 
>>> 1 is (not None) # is 1 the same object as True? 
False 
+0

「is not」は単一の演算子であることに言及することが重要です。 'Trueは(1ではない) - > False'、' Trueは1 - > True'ではありません。したがって、「None None」が返すものは無関係です。 –

+0

@PavelAnossov OPが '(not None)'を使用しているため、 'not None'の戻り値は関連しています。 – delnan

+0

@delnan:正確には、OPが1つの演算子であることを逃したためです。 'op1 is(not None)'が期待されたようです。どちらが真ではなく「偽」であろうか。 –

3

NoneTrueFalseはシングルトンです。それらをテストするためにisを使用しても安全なように、これらの値のそれぞれのインスタンスが1つだけ

>>> id(True) 
8851952 
>>> id(False) 
8851920 
>>> id(None) 
8559264 
>>> id(not None) 
8851952 
>>> id(1 == 0) 
8851920 
>>> id(1 == 1) 
8851952 
+0

'None'では' False'と 'True'のために実装の詳細かもしれません。それにもかかわらず、 'xxxが真であるかどうかをテストする:'私には馬鹿に聞こえる。単純に '' xxx: 'ならばもっと良いはずです。 – glglgl

+0

@glglgl私は同意します。私はちょうど '真(true)'と '偽(false)'を議論に導入しました。つまり、 'is'演算子を使用してブール値'(not None) 'と比較します。これは他のコメントで説明した' is not'演算子と同じではありません。 –

+0

@glglgl 'xxx is True'の病理学的なケースを簡単に思い出すことができます:Linuxプロセスのやり方でエラーコードを返しました。関数が成功するとTrueを返し、失敗するとエラーコードを返します。エラーコードは0より大きい可能性があり、したがってtrueに評価されます。確かに、これを行うにははるかに良い方法がありますが、ここでは病理学的になっています。 (確かに上記のことは、必要な 'if!result:'とlinux-esqueの成功のためのゼロよりも読者にとって意味があります)。 – RoadieRich

0

が...ありPythonは読みやすい、それはより人間にするために英語の構文をエミュレートしようとしますが、この例ではオペレータ優先順位は少し混乱します。英語で

>>> val is not None 
True 

valNoneと同じオブジェクトによって表される値を持っていない場合、我々は求めています。上の例ではval=10ですので、答えは(正しく)Trueです。あなたはステートメント逐語を分解し、することを想定している論理的、文法的な観点からしかし

、:適切なpatenthesesに囲まれ、

>>> val is (not None) 
False 

、あなたの期待される結果を返します(False )。

@Martijn Pietersが指摘するように、is notis an operator in its own rightとして、ここで働いている唯一の演算子です。

あなたは何のスペースが含まれていないだけの演算子を使用して、非あいまいな文として、それを書きたい場合は、あなたが書くことができる:

>>> not (val is None) 
True 

しかし、それはあなたが英語で意図した文を「言う」だろうかではありません、あるいは擬似コードで書き込むことさえできます。

関連する問題